MVC Futures强烈输入带有区域和重复控制器名称的RenderAction

时间:2011-07-06 13:29:56

标签: asp.net-mvc asp.net-mvc-areas asp.net-mvc-futures

我正在尝试使用MVC Futures库中强类型的Html.RenderAction

我在我的主要HomeController(area =“”)上有一个导航操作,我试图从我的Site.Master调用

<% Html.RenderAction<HomeController>(x=>x.Navigation()); %>

这很好用,直到我将另一个HomeController添加到我的Admin便携区域。然后我开始出现以下错误:

  

找到匹配的多种类型   控制器名为'Home'。这个可以   如果服务于此的路线发生   请求不指定名称空间   搜索匹配的控制器   请求。如果是这种情况,   通过呼叫注册这条路线   'MapRoute'方法的重载   采用'名称空间'参数。

     

'Home'的请求找到了   以下匹配控制器:   Areas.Admin.Controllers.HomeController   Web.Controllers.HomeController

我能够通过使用以下非mvccontrib强类型RenderAction方法来解决此问题。我宁愿在页面上没有这种非强类型的方法,是否有办法使mvccontrib方法接受一个区域,或者让他们知道根据路由或指定的Controller的命名空间生成区域。 / p>

<% Html.RenderAction("Navigation", "Home", new { area = "" }); %>

我已经添加到我的global.asax.cs文件中以支持具有默认区域的多个控制器,如下所示,并且我还验证了这是我的控制器的正确命名空间。

_routeCollection.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new[] { "Web.Controllers" });

2 个答案:

答案 0 :(得分:2)

显然目前在期货项目中没有这方面的支持,或者他们从Futures v1.0开始改变它。我使用了反射器来反汇编期货库并找到了RenderAction方法的源代码,并修改了它来解析Controller命名空间中的区域,并在处理之前将其添加到RouteValues中。我假设我可能不得不为ActionLink做类似的事情,如果我希望它们以相同的方式行事。

以下是我使用的代码示例,希望这可以在将来帮助其他人。我可能会创建新方法,表明它将解析区域,而不是像我到目前为止的重载

public static void RenderAction<TController>(this HtmlHelper helper, Expression<Action<TController>> action) where TController : Controller
{
    var ctrlNamespace = typeof(TController).Namespace;

    int areaStart = ctrlNamespace.IndexOf(".Areas.");
    if (areaStart > -1) 
    {
        ctrlNamespace = ctrlNamespace.Substring(areaStart + 7);
        int areaEnd = ctrlNamespace.IndexOf(".");
        ctrlNamespace = ctrlNamespace.Substring(0, areaEnd);
    }
    else
    {
        ctrlNamespace = String.Empty; //default area
    }

    helper.ViewContext.RouteData.Values.Add("area", ctrlNamespace);

    RouteValueDictionary routeValuesFromExpression = ExpressionHelper.GetRouteValuesFromExpression<TController>(action);
    foreach (KeyValuePair<string, object> pair in helper.ViewContext.RouteData.Values)
    {
        if (!routeValuesFromExpression.ContainsKey(pair.Key))
        {
            routeValuesFromExpression.Add(pair.Key, pair.Value);
        }
    }

    helper.RenderRoute(routeValuesFromExpression);
}

答案 1 :(得分:0)

为了支持MVC中的多个控制器,您需要在默认路由中添加命名空间。

有关详细信息,请参阅此答案:Question 2627699