Как работает RouteBase.GetRouteData или указатели для реализации сопоставления с образцом - PullRequest
1 голос
/ 20 июля 2011

Я смотрю на реализацию опции для определения определенных шаблонов URL, которые мой HttpModule должен игнорировать.

Я хочу иметь возможность определять "фильтры", такие как:

/Admin/{*}
/Products/{*}/Search

Что должно отфильтровывать URL-адреса, такие как:

http://mysite.com/admin/options
http://mysite.com/products/toys/search

, но не отфильтровывать http://mysite.com/orders http://mysite.com/products/view/1

Схоже с тем, как ASP.NET MVC регистрирует маршрутыкоторые соответствуют шаблону.Я посмотрел на исходный код Route Debugger Фила Хаака и подумал, что он может показать мне, как работает RouteBase.GetRouteData (..), однако он просто использует его.

Кажется, я не могу найти никаких примеров, которыепокажите, как на самом деле работает этот RouteBase.GetRouteData (или найдите фактический исходный код для него).

Если кто-то может указать мне правильное направление для того, как это (или сопоставление с образцом) обычно реализуется, это было бы здорово.

PS: я уже знаю, что могу использовать регулярные выражения, но хотел бы иметь очень специфический набор правил.

1 Ответ

1 голос
/ 21 июля 2011

Обновление

Поскольку вы хотите написать HttpModule, который очень близко имитирует работу System.Web.Routing, то, возможно, вам следует использовать ILSpy и отражать сборкуи посмотрите, что он делает?

Оригинальный ответ (сохранен для потомков)

Непонятно, говорите ли вы о ASP.NET MVC или о Spring MVC или оРасширения Spring.NET для ASP.NET MVC.Если это первое или третье:

Для вашего первого примера:

Admin/{*}

решение № 1 ниже будет решать это.Для вашего второго примера:

Products/{*}/Search, решение № 2 будет решать его (если есть необходимость проверить или действительно иметь что-то действительное там)

Два решения:

  1. Создание маршрутов, которые принимают эти параметры (но ничего с ними не делают или не заботятся о них)
  2. Создают ActionFilter, который проверяет запрос этих параметров (из маршрута) изатем заменяет их тем, что на самом деле должно быть.

Решение 1

В разделе маршрутов в global.asax.cs:

routes.MapRoute("AdminAnything",
    "Admin/{*anything}",
    new { controller = admin, action = "Show" }
    );

Это приведет кследующие URL-адреса для разрешения действия Show в контроллере администратора (игнорируя при этом входные данные по своему усмотрению):

Admin/Options  
Admin/Anything-I-Want-here

Решение 2

Теперь второй способ сложнее, поскольку у вас действительно естьчто-то среднее между ними.

Пример ввода:

Product/{*}/Search  

Вы можете написать ActionFilter, который перехватывает запрос, просматривает его и заменяет это значение тем, что вы хотите.

Во-первых, нНеобходимый маршрут:

routes.MapRoute("ProductSearch",
    "Products/{searchType}/Search,
    new { controller = "Products", action = "Search" }
    );

Затем действие вашего контроллера:

public ActionResult Search(string searchType)
{
    //do nothing with searchType here.
}

Если вы хотите заменить это чем-то, вы можете отправить в скрытое поле формы в вашем представлении и обработать это.в Actionfilter:

public class SearchValidationActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if(filterContext.ActionParameters.ContainsKey("searchType") && filterContext.HttpContext.Request.Headers["hiddenSearchType"].IsNotNullOrEmpty()))
        {
        var actualSearchType = filterContext.ActionParameters["hiddenSearchType"] as SearchType;
        var searchType = filterContext.ActionParameters["searchType"];
        if (actualSearchType != null)
        {
            if (searchType.IsNullOrEmpty())
        {
            filterContext.Result = new SearchRedirectResult(actualSearchType.Name);
        }
        else if (!actualSearchType.Name.Equals(searchType))
        {
            filterContext.Result = new SearchRedirectResult(actualSearchType.Name,);
        }
        }
    }
        base.OnActionExecuting(filterContext);
    }
}

По сути, решение № 2 принимает все, и, основываясь на скрытом типе поиска, передает его фактическому типу поиска.

...