Цель данного примера - демонстрация практических возможностей того, что мы узнали о системе маршрутизации 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>
Теперь после запуска приложения, в браузере будет доступен только один рисунок. Что и требовалось получить. А
вот ссылка на проект.