【问题标题】:No need for separate controllers or actions for each view solution - understanding the code每个视图解决方案都不需要单独的控制器或操作 - 了解代码
【发布时间】:2015-09-07 23:03:31
【问题描述】:

this article 有两件事我无法掌握。它解释了使用 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”和“x-controller”键下。控制器和动作下面的几行存储在“控制器”和“动作”键下。

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

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?此外,为什么有人决定将它们存储在动作和控制器变量中并覆盖“动作”和“控制器”键下的数据(第 3,4 行)?

【问题讨论】:

  • 如果我不想知道,那我也不会问。有时你可以通过了解细节来了解更多信息,你知道的。
  • 对于它的价值,文章中使用的方法不是一个很好的解决方案。它将路由带到控制器内部不属于它的地方。更好的方法是继承Route 类,覆盖GetRouteData 并始终返回相同的controlleraction(如果需要,还可以选择存储原始值)。然后使用自定义的Route 类来注册所有的路由。

标签: c# asp.net-mvc httphandler


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

没有。目的是将原始请求值存储在“x-action”、“x-controller”中,然后根据需要覆盖“action”、“controller”,同时在处理的后期仍然可以访问原始值。 “x-action”、“x-controller”只是被用作临时变量。它们被存储在 RouteData 中,因为一旦调度方法完成,任何本地变量都将超出范围。

  1. 注意正文中的前两行。为什么要在字符串对象上调用 toString?

RouteData.Values 通过字符串索引器返回一个对象,因此是 ToString。 IE。 RouteData.Values["MyValue"] 返回一个对象而不是字符串。

此外,为什么有人决定将它们存储在动作和控制器中 变量并覆盖“动作”和“控制器”键下的数据 (第 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 处理程序中,我们将这些原始值拉回,以便我们可以为原始控制器请求生成视图。

【讨论】:

  • 我想知道这个人是如何编写它的,例如,如果 msdn 上没有记录 RouteElement 或 RouteConfiguration 类。那么这些类的来源可用吗?
  • 下载文章代码看看。 using Anterec.ControllerLess.Configuration; 建议他们有一些自定义 dll。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多