Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc asp.net mvc按名称和区域查找控制器_Asp.net Mvc_Controller_Asp.net Mvc Routing - Fatal编程技术网

Asp.net mvc asp.net mvc按名称和区域查找控制器

Asp.net mvc asp.net mvc按名称和区域查找控制器,asp.net-mvc,controller,asp.net-mvc-routing,Asp.net Mvc,Controller,Asp.net Mvc Routing,我的目标是从它的名称和区域中找到一个控制器。如果我当前的httpContext与待查找控制器位于同一区域内,则我已成功完成此操作。但是,我无法打电话给控制器工厂,以考虑该区域。这是我的密码: public static ControllerBase GetControllerByName(this HtmlHelper htmlHelper, string controllerName) { IControllerFactory factory = ControllerBui

我的目标是从它的名称和区域中找到一个控制器。如果我当前的
httpContext
与待查找控制器位于同一区域内,则我已成功完成此操作。但是,我无法打电话给
控制器工厂
,以考虑该区域。这是我的密码:

public static ControllerBase GetControllerByName(this HtmlHelper htmlHelper, string controllerName)
    {
      IControllerFactory factory = ControllerBuilder.Current.GetControllerFactory();
      IController controller = factory.CreateController(htmlHelper.ViewContext.RequestContext, controllerName);
      if (controller == null)
      {
        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, "The IControllerFactory '{0}' did not return a controller for the name '{1}'.", factory.GetType(), controllerName));
      }
      return (ControllerBase)controller;
    }
由于它将
RequestContext
作为一个参数,因此我在其中添加了一个路由值“area”,但没有任何更改。我可以通过requestContext做些什么来考虑这个区域吗?我需要重写控制器工厂吗?如果需要,具体是什么处理区域差异

更新:

以下是我的区域注册示例:

public class StoresAreaRegistration : AreaRegistration
  {
    public override string AreaName { get { return "Stores"; } }

    public override void RegisterArea(AreaRegistrationContext context)
    {
      context.MapRoute(
          AreaName,
          AreaName + "/{controller}/{action}/{id}",
          new { area = AreaName, controller = "Home", action = "Index", id = UrlParameter.Optional }
      );
    }
  }

用于定位控制器的区域和名称空间位于RequestContext的RoutedData中。默认情况下,它们根据您当前提供的请求进行填充,如果您需要更改它们,则必须在调用CreateController之前进行更改。当找不到控制器时,您可能会遇到异常,因此您也必须对此进行解释

更新:注意,您必须创建一个新的RequestContext。如果您重用现有的一个,它将影响稍后在此请求中的操作和视图的解析

var tempRequestContext = new RequestContext(Request.RequestContext.HttpContext, new RouteData());
tempRequestContext.RouteData.DataTokens["Area"] = "";
tempRequestContext.RouteData.DataTokens["Namespaces"] = "YourCompany.Controllers";
var controller = ControllerBuilder.Current.GetControllerFactory()
                .CreateController(tempRequestContext, "ControllerName");

if(controller != null)
{
    //TODO: Implement your logic here
}

您是否尝试过
RequestContext.RouteData
?@cheesemacfly,是--
htmlHelper.ViewContext.RequestContext.RouteData.DataTokens[“area”]=areaName
htmlHelper.ViewContext.RequestContext.RouteData.Values[“area”]=areaName
都尝试了,但都没有成功。您是如何在
Global.asax
中声明此路由的?实际上,该路由是在AreaRegistration.cs文件中声明的。我已将其添加到问题中。您无权访问
GetControllerByName()
函数中的
Request.RequestContext
对象?您好,稍有不同的错误,尽管我必须更改[“名称空间”]的[“名称空间”](没有使用区域,所以我不知道该键是否也需要小写)。Thanks我在我的代码中使用大写,效果很好,我不知道为什么大写和小写会有不同的结果。在MVC 5中,名称空间值显然需要IEnumerable而不仅仅是字符串。所以使用:
tempRequestContext.RouteData.DataTokens[“Namespaces”]=new List{“YourCompany.Controllers”};
它应该同时接受这两个名称空间。如果您只传入一个名称空间,您可以给它一个字符串。您不必将其包装在列表中传递。
DataTokens[“Namespaces”]
所期望的类型是
object
类型。