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
类型。