不需要为每个视图解决方案使用单独的控制器或操作——理解代码

本文关键字:操作 控制器 代码 单独 视图 解决方案 不需要 | 更新日期: 2023-09-27 18:11:40

在这篇文章中有两件事我不能理解。它解释了使用ASP的方法。. NET MVC,而不需要为每个视图单独的控制器或操作。

1)在DispatchRequest方法中:

private void DispatchRequest(IControllerFactory controllerFactory, string controller, string action)
    {
        var route = GetRoute(controller, action);
        _requestContext.RouteData.Values["x-action"] = action;
        _requestContext.RouteData.Values["x-controller"] = controller;
        if (route != null)
        {
            _requestContext.RouteData.Values["controller"] = route.Controller;
            _requestContext.RouteData.Values["action"] = route.Action;
            if (route.Area != string.Empty)
            {
                _requestContext.RouteData.DataTokens["area"] = route.Area;
            }
            controller = route.Controller;

操作和控制器字符串存储在"x-action"answers"x-controller"键下。控制器和动作下面的几行存储在"控制器"answers"动作"键下。

两对(控制器和动作)都是字符串,这些对不是一样的吗?在我看来他们是。为什么要重复不必要的数据?

2)控制器中ControllerLessController:

public virtual ActionResult Index()
    {
        var action = RouteData.Values["x-action"].ToString();
        var controller = RouteData.Values["x-controller"].ToString();
        RouteData.Values["action"] = action;
        RouteData.Values["controller"] = controller;
        if (RouteData.Values["area"] != null)
        {
            RouteData.DataTokens["area"] = RouteData.Values["area"].ToString();
        }
        return View(action);
    }
}

注意正文的前两行。为什么在字符串对象上调用toString ?此外,为什么有人决定将它们存储在动作和控制器变量中,并覆盖"动作"answers"控制器"键下的数据(第3,4行)?

不需要为每个视图解决方案使用单独的控制器或操作——理解代码

  1. 两对(控制器和动作)都是字符串,这些对不一样吗?在我看来他们是。为什么要复制数据不必要的?

。其目的是将原始请求值存储在"x-action"、"x-controller"中,然后根据需要覆盖"action"、"controller",同时在处理的后期阶段仍然可以访问原始值。"x-action","x-controller"只是用作临时变量。它们被存储在RouteData中,因为一旦分派方法完成,任何局部变量都将超出作用域。

  • 注意正文的前两行。为什么在字符串对象上调用toString ?
  • RouteData。Values通过字符串索引器返回一个对象,因此ToString。即。RouteData.Values["MyValue"]返回一个非字符串的对象。

    此外,为什么有人决定将它们存储在action和controller中变量,并覆盖"action"answers"controller"键下的数据(3号线,4)?

    这又回到了第1节中的TempData思想。一个操作请求进来。通常在MVC中,这将转换为带有视图的控制器,但在这个无控制器示例中,无控制器操作需要映射到无控制器处理程序。

    因此,在DispatchRequest中,这些被覆盖以指向无控制器处理程序class ControllerLessController : Controller

    注意,这是在控制器选择之前发生的

    然后MVC以正常方式处理请求,但由于在Dispatch中切换,MVC不去寻找最初请求的控制器(因为没有一个),而是使用注入的无控制器控制器:

    _requestContext.RouteData.Values["action"] = _configuration.DefaultAction;
    controller = _configuration.DefaultController;
    

    因此,正常的请求处理继续进行,并降落在无控制器控制器内。此时,我们需要返回并找到最初请求的视图。

    public virtual ActionResult Index()
        {
            var action = RouteData.Values["x-action"].ToString();
            var controller = RouteData.Values["x-controller"].ToString();
            RouteData.Values["action"] = action;
            RouteData.Values["controller"] = controller;
            if (RouteData.Values["area"] != null)
            {
                RouteData.DataTokens["area"] = RouteData.Values["area"].ToString();
            }
            return View(action);
        }
    

    这个信息被存储在"x-action"路由值中,所以他们把它拉出来并返回原始请求的视图:

    return View(action);

    ,

    var action = RouteData.Values["x-action"].ToString();

    基本上你只有一个重定向/拦截层。我们将所有没有控制器的操作重定向到某个处理程序,在本例中是ControllerLessController。在此之前,我们需要将原始请求参数存储在"x-action"变量中。然后,一旦在ControllerLessController处理程序中,我们将这些原始值拉出来,这样我们就可以为原始控制器请求生成视图。