gpt4 book ai didi

asp.net-mvc - MVC 路由发生在哪个请求事件中。

转载 作者:可可西里 更新时间:2023-11-01 16:28:29 28 4
gpt4 key购买 nike

我已经遍历了 MVC 请求生命周期,但我仍然不清楚根据注册路由将请求路由到处理程序的位置。

我们使用 url 发出 MVC 请求,然后它会找到 Controller 并提供正确的 cshtml 页面。由于 url 没有任何资源类型,http 模块事件或 http 处理程序如何区分 MVC 请求并将其传递给正确的 Controller 。

最佳答案

你有this document来自 Microsoft 的 ASP .Net 站点,详细描述了 MVC 5 请求生命周期以及它如何集成到 ASP .Net 生命周期中。 pdf 中图表的某些部分本身链接到 msdn 中的相关页面。

另一个很好的资源是 this set of slides来自 Lukasz Lysic,详细解释了 MVC 4 中的请求生命周期。

编辑:我不喜欢仅链接的答案,因此我在下面添加了更多详细信息。


在您的机器级别 web.config 上,您将看到 UrlRoutingModule注册为IHttpModule .例如,在我的电脑上我有:

<system.web>
<httpModules>
...
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
...
</httpModules>
<system.web>

关于PostResolveRequestCache应用程序事件,路由模块遍历 RouteCollection 中的所有路由属性并搜索具有与 HTTP 请求格式匹配的 URL 模式的路由。当模块找到匹配的路由时,它会检索 IRouteHandler该路线的对象。从路由处理程序中,模块获得 IHttpHandler。对象并将其用作当前请求的 HTTP 处理程序(调用其 ProcessRequest 方法或其异步方法 BeginProcessRequestEndProcessRequest)。

  • 可以查看UrlRoutingModule代码here在 Microsoft .Net 引用源网站上。

对于 MVC 应用程序,当您使用 MapRoute 扩展方法在 global.asax 中添加路由时,MVCRouteHandler 是已创建。

  • 检查RouteCollectionExtensions 中的MapRoute 方法类:

    public static Route MapRoute(this RouteCollection routes, string name, string url, object defaults, object constraints, string[] namespaces)
    {
    if (routes == null)
    {
    throw new ArgumentNullException("routes");
    }
    if (url == null)
    {
    throw new ArgumentNullException("url");
    }

    Route route = new Route(url, new MvcRouteHandler())
    {
    Defaults = CreateRouteValueDictionaryUncached(defaults),
    Constraints = CreateRouteValueDictionaryUncached(constraints),
    DataTokens = new RouteValueDictionary()
    };

    ConstraintValidation.Validate(route);

    if ((namespaces != null) && (namespaces.Length > 0))
    {
    route.DataTokens[RouteDataTokenKeys.Namespaces] = namespaces;
    }

    routes.Add(name, route);

    return route;
    }

因此,当请求与 MVC 路由匹配时,它将由 MvcRouteHandler 处理。如上所述,路由的 IRouteHandler 的目的是获取一个 IHttpHandler ,应用程序将使用该 IHttpHandler 继续处理请求。 MvcRouteHandler 将返回一个 MvcHandler,它是 MVC 特定管道的入口点。

  • 检查 MvcRouteHandlerGetHttpHandler 方法类:

    protected virtual IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
    requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
    return new MvcHandler(requestContext);
    }

MVC 特定的管道基本上以 ProcessRequest 方法(或异步 BeginProcessRequest/EndProcessRequest)开始。 MvcHandler 将获得 IControllerFactory(默认情况下,将使用 DefaultControllerFactory,除非您使用 ControllerBuilder.Current.SetDefaultControllerFactory 注册您自己的global.asax Application_Start),使用它根据当前路由值创建 Controller 实例并启动 Controller 执行。

  • 检查 MvcHandlerProcessRequest 方法类:

    protected internal virtual void ProcessRequest(HttpContextBase httpContext)
    {
    IController controller;
    IControllerFactory factory;
    ProcessRequestInit(httpContext, out controller, out factory);

    try
    {
    controller.Execute(RequestContext);
    }
    finally
    {
    factory.ReleaseController(controller);
    }
    }

    private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
    {
    // If request validation has already been enabled, make it lazy. This allows attributes like [HttpPost] (which looks
    // at Request.Form) to work correctly without triggering full validation.
    // Tolerate null HttpContext for testing.
    HttpContext currentContext = HttpContext.Current;
    if (currentContext != null)
    {
    bool? isRequestValidationEnabled = ValidationUtility.IsValidationEnabled(currentContext);
    if (isRequestValidationEnabled == true)
    {
    ValidationUtility.EnableDynamicValidation(currentContext);
    }
    }

    AddVersionHeader(httpContext);
    RemoveOptionalRoutingParameters();

    // Get the controller type
    string controllerName = RequestContext.RouteData.GetRequiredString("controller");

    // Instantiate the controller and call Execute
    factory = ControllerBuilder.GetControllerFactory();
    controller = factory.CreateController(RequestContext, controllerName);
    if (controller == null)
    {
    throw new InvalidOperationException(
    String.Format(
    CultureInfo.CurrentCulture,
    MvcResources.ControllerBuilder_FactoryReturnedNull,
    factory.GetType(),
    controllerName));
    }
    }

这应该解释传入请求如何与 MVC 中的 Controller 匹配。对于 MVC 管道的其余部分,请查看帖子开头的链接!

关于asp.net-mvc - MVC 路由发生在哪个请求事件中。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23308804/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com