【问题标题】:MVC Futures strongly typed RenderAction with Areas and duplicate Controller Names具有区域和重复控制器名称的 MVC Futures 强类型 RenderAction
【发布时间】:2011-07-06 13:29:55
【问题描述】:

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

我的主 HomeController (area = "") 上有一个 Navigation 操作,我正试图从我的 Site.Master 调用它

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

在我将另一个 HomeController 添加到我的 Admin 便携式区域之前,这非常有效。然后我开始出现以下错误:

找到多个匹配的类型 名为“Home”的控制器。这个可以 如果服务于此的路线发生 请求没有指定命名空间 搜索匹配的控制器 请求。如果是这种情况, 通过调用 'MapRoute' 方法的重载 接受一个“命名空间”参数。

“主页”请求已找到 以下匹配的控制器: Areas.Admin.Controllers.HomeController Web.Controllers.HomeController

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

<% 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" });

【问题讨论】:

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


    【解决方案1】:

    显然目前futures项目不支持这个,或者他们从Futures v1.0开始改变了它。我使用反射器对futures库进行了反汇编,找到了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);
    }
    

    【讨论】:

      【解决方案2】:

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

      更多详情请参阅此答案:Question 2627699

      【讨论】:

      • 我已经这样做了,我应该在我的原始帖子中注意到这一点。我在我的 global.asax.cs _routeCollection.MapRoute("Default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.可选 }, new[] { "Web.Controllers" });
      猜你喜欢
      • 2011-04-26
      • 1970-01-01
      • 1970-01-01
      • 2011-02-12
      • 1970-01-01
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多