Пример использования собственного обработчика маршрута ImageRouteHandl­er

Цель данного примера - демонстрация практических возможностей того, что мы узнали о системе маршрутизации ASP.NET  в данной статье. Пример, не скажу, что надуманный, однако в целях демонстрации думаю подходит. Хотя был подобный вопрос на форумах MSDN. Задача следующая: нужно ограничить доступ к неким ресурсам, например к файлам изображений для определённых доменов.  Для этого создадим простое приложение ASP.NET MVC (с таким же успехом можно было использовать и приложение Web Forms). Определим маршрут по которому будут выдаваться эти файлы.
using System.Web.Mvc;
using System.Web.Routing;
 
namespace ImageFilter
{
  public class MvcApplication : System.Web.HttpApplication
  {
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
      filters.Add(new HandleErrorAttribute());
    }
 
    public static void RegisterRoutes(RouteCollection routes)
    {
      //Маршрут идёт первым, чтобы не попал в IgnoreRoute.
      routes.Add("ImagesRoute", 
        new Route("myImages/{filename}", new ImageRouteHandler()));
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
      routes.MapRoute(
          "Default",
          "{controller}/{action}/{id}",
          new { controller = "Home", action = "Index", id = UrlParameter.Optional }
      );
    }
 
    protected void Application_Start()
    {
      AreaRegistration.RegisterAllAreas();
 
      RegisterGlobalFilters(GlobalFilters.Filters);
      RegisterRoutes(RouteTable.Routes);
    }
  }
}
Как видно из кода вместо стандартного обработчика MvcRouteHandler используем собственный обработчик ImageRouteHandler.
using System;
using System.IO;
using System.Web;
using System.Web.Routing;
using System.Collections.Specialized;
 
namespace ImageFilter
{
  public class ImageRouteHandler : IRouteHandler
  {
    public ImageRouteHandler()
    {
      ImageExtensions = new NameValueCollection();
      ImageExtensions.Add(".bmp", "Image/bmp");
      ImageExtensions.Add(".gif", "Image/gif");
      ImageExtensions.Add(".jpg", "Image/jpg");
      ImageExtensions.Add(".png", "Image/png");
    }
    //В целях демонстрации используем домен msdr,
    //главное не localhost, а что угодно.
    private const string DenyDomainName = "msdr";
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
      //Извлекаем имя файла из данных маршрута.
      string filename = requestContext.RouteData.Values["filename"] as string;
 
      //Конечно тут могла быть более сложная проверка на основе регулярных
      //выражений, но всё упростил.
      if(requestContext.HttpContext.Request.Url.ToString().Contains(DenyDomainName))
      {
        return null;
      }
      else
      {
        requestContext.HttpContext.Response.Clear();
        requestContext.HttpContext.Response.ContentType
          = getContentType(requestContext.HttpContext.Request.Url.ToString());
        string filepath = requestContext.HttpContext
          .Server.MapPath("~/Content/MyImages/" + filename );
        requestContext.HttpContext.Response.WriteFile(filepath);
        requestContext.HttpContext.Response.End();
      }
      return null;
    }
 
    private string getContentType(String path)
    {
      string contentType = ImageExtensions[Path.GetExtension(path)];
      if (contentType == null)
        throw new Exception("Формат файла не поддерживается ситемой.");
      return contentType;
    }
    private NameValueCollection ImageExtensions;
  }
}
Код контроллера стандартный.
using System.Web.Mvc;
 
namespace ImageFilter.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/
 
        public ActionResult Index()
        {
            return View();
        }
 
    }
}
А представление следующее.
@{
    Layout = null;
}
 
<!DOCTYPE html>
 
<html>
<head>
    <title>Home</title>
</head>
<>
    <div>
      <span>Рисунок с прямым путём файла</span>
      <img src="../../Content/MyImages/Koala.jpg" height="300px" alt="" />
      <br />
      <span>Рисунок через маршрутизацию</span>
      <img src="../../MyImages/Koala.jpg" height="300px" alt="" />
    </div>
</>
</html>
Теперь после запуска приложения, в браузере будет доступен только один рисунок. Что и требовалось получить. А вот ссылка на проект.