T4MVC 和不同区域的重复控制器名称

发布于 2024-08-31 23:29:08 字数 1001 浏览 6 评论 0原文

在我的应用程序中,我在默认区域(应用程序根目录中)和名为 Manage 的区域中都有名为 Snippets 的控制器。我使用 T4MVC 和自定义路由,如下所示:

routes.MapRoute(
    "Feed",
    "feed/",
    MVC.Snippets.Rss()
);

我收到此错误:

发现多种类型与名为“snippets”的控制器匹配。如果服务此请求的路由 ('{controller}/{action}/{id}/') 未指定命名空间来搜索与请求匹配的控制器,则可能会发生这种情况。如果是这种情况,请通过调用采用“namespaces”参数的“MapRoute”方法的重载来注册此路由。

对“snippets”的请求已找到以下匹配的控制器: Snippets.Controllers.SnippetsController Snippets.Areas.Manage.Controllers.SnippetsController

我知道 MapRoute 有采用 namespaces 参数的重载,但 T4MVC 支持没有此类重载。也许我错过了什么?可能的语法可以是:

routes.MapRoute(
    "Feed",
    "feed/",
    MVC.Snippets.Rss(),
    new string[] {"Snippets.Controllers"}           
);

或者,对我来说将命名空间作为 T4MVC 属性似乎很好:

routes.MapRoute(
    "Feed",
    "feed/",
    MVC.Snippets.Rss(),
    new string[] {MVC.Snippets.Namespace}           
);

提前致谢!

In my application I have controller named Snippets both in default area (in application root) and in my area called Manage. I use T4MVC and custom routes, like this:

routes.MapRoute(
    "Feed",
    "feed/",
    MVC.Snippets.Rss()
);

And I get this error:

Multiple types were found that match the controller named 'snippets'. This can happen if the route that services this request ('{controller}/{action}/{id}/') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

The request for 'snippets' has found the following matching controllers:
Snippets.Controllers.SnippetsController
Snippets.Areas.Manage.Controllers.SnippetsController

I know that there are overloads for MapRoute that take namespaces argument, but there are no such overloads with T4MVC support. May be I'm missing something? The possible syntax can be:

routes.MapRoute(
    "Feed",
    "feed/",
    MVC.Snippets.Rss(),
    new string[] {"Snippets.Controllers"}           
);

or, it seems quite good to me to have namespace as T4MVC property:

routes.MapRoute(
    "Feed",
    "feed/",
    MVC.Snippets.Rss(),
    new string[] {MVC.Snippets.Namespace}           
);

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

徒留西风 2024-09-07 23:29:08

有道理。我想你只是第一个遇到这种情况的人。尝试用以下内容替换 T4MVC.tt 中的所有 MapRoute 方法:

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result) {
        return MapRoute(routes, name, url, result, null /*namespaces*/);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults) {
        return MapRoute(routes, name, url, result, defaults, null /*constraints*/, null /*namespaces*/);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, string[] namespaces) {
        return MapRoute(routes, name, url, result, null /*defaults*/, namespaces);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, object constraints) {
        return MapRoute(routes, name, url, result, defaults, constraints, null /*namespaces*/);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, string[] namespaces) {
        return MapRoute(routes, name, url, result, defaults, null /*constraints*/, namespaces);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, object constraints, string[] namespaces) {
        // Start by adding the default values from the anonymous object (if any)
        var routeValues = new RouteValueDictionary(defaults);

        // Then add the Controller/Action names and the parameters from the call
        foreach (var pair in result.GetRouteValueDictionary()) {
            routeValues.Add(pair.Key, pair.Value);
        }

        var routeConstraints = new RouteValueDictionary(constraints);

        // Create and add the route
        var route = new Route(url, routeValues, routeConstraints, new MvcRouteHandler());

        if (namespaces != null && namespaces.Length > 0) {
            route.DataTokens = new RouteValueDictionary();
            route.DataTokens["Namespaces"] = namespaces;
        }

        routes.Add(name, route);
        return route;
    }

请注意,无需 T4MVC 的帮助,您只需编写即可在控制器命名空间上获得强类型:

 string[] { typeof(MyApplication.Controllers.SnippetsController).Namespace }

我应该补充一点,理想情况下,您根本不必传递命名空间,因为您针对特定控制器的意图已在 MVC.Snippets.Rss() 调用中捕获。然而,如果不对 T4MVC 进行重大更改,我找不到一种明显的方法来完成这项工作。

无论如何,请检查并测试更改,并让我知道它对您有何作用。如果看起来不错,我会加入。

谢谢!

Makes sense. I guess you're just the first one to run into this. Try replacing all the MapRoute methods in T4MVC.tt by the following:

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result) {
        return MapRoute(routes, name, url, result, null /*namespaces*/);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults) {
        return MapRoute(routes, name, url, result, defaults, null /*constraints*/, null /*namespaces*/);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, string[] namespaces) {
        return MapRoute(routes, name, url, result, null /*defaults*/, namespaces);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, object constraints) {
        return MapRoute(routes, name, url, result, defaults, constraints, null /*namespaces*/);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, string[] namespaces) {
        return MapRoute(routes, name, url, result, defaults, null /*constraints*/, namespaces);
    }

    public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, object constraints, string[] namespaces) {
        // Start by adding the default values from the anonymous object (if any)
        var routeValues = new RouteValueDictionary(defaults);

        // Then add the Controller/Action names and the parameters from the call
        foreach (var pair in result.GetRouteValueDictionary()) {
            routeValues.Add(pair.Key, pair.Value);
        }

        var routeConstraints = new RouteValueDictionary(constraints);

        // Create and add the route
        var route = new Route(url, routeValues, routeConstraints, new MvcRouteHandler());

        if (namespaces != null && namespaces.Length > 0) {
            route.DataTokens = new RouteValueDictionary();
            route.DataTokens["Namespaces"] = namespaces;
        }

        routes.Add(name, route);
        return route;
    }

Note that you can get strong typing on the controller namespace without T4MVC's help simply by writing:

 string[] { typeof(MyApplication.Controllers.SnippetsController).Namespace }

I should add that ideally, you would not have to pass the Namespaces at all, since your intent to target a specific controller is already captured in the MVC.Snippets.Rss() call. However, I couldn't find an obvious way to make this work without big changes to T4MVC.

Anyway, please review and test the change, and let me know how it works for you. If it looks good, I'll get it in.

Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文