在 MVC 的 url 中不指定区域名称的情况下设置到区域的路由

Set a route to an area without specifying the area name in the url in MVC

我有一个 MVC 4 应用程序。在该应用程序中,我有某些区域,其 URL 未正确解析。 LocationAreaRegistration.cs如下:

context.MapRoute(
            "Location_default",
            "{culture}/{controller}/{action}/{id}",
            new { culture = "en", action = "LocationIndex", id = UrlParameter.Optional },
            new { controller = "(LocationIndex)" }
        );

我的route.config如下:

routes.MapRoute(
                 name: "Default",
                 url: "{culture}/{controller}/{action}/{id}",
                 defaults: new { culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
                 namespaces: new[] { "Locator.Areas.Location.Controllers" }
               ).DataTokens.Add("area", "Location");

我也试过改变 route.config 如下:

routes.MapRoute(
             name: "Default",
             url: "{culture}/{controller}/{action}/{id}",
             defaults: new { culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
             namespaces: new[] { "Locator.Areas.Location.Controllers" }
           );

None 的方法有效,我得到 The resource cannot be found 错误。

然而,当我按如下方式更改 LocationAreaRegistration.cs 时,它起作用了:

context.MapRoute(
            "Location_default",
            "{culture}/Location/{controller}/{action}/{id}",
            new { culture = "en", action = "LocationIndex", id = UrlParameter.Optional },
            new { controller = "(LocationIndex)" }
        );

但我不希望 URL 包含 Location(区域名称)。我做错了什么?

编辑

我将要做的 URL 有点像:

http://localhost/en/LocationIndex/LocationIndex

这里en是当前文化,Homecontroller名字,Indexaction method名字。

要使 Location 区域成为 MVC 应用程序的默认路由集,您只需按如下方式定义 RouteConfig.cs

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default_Localized",
            url: "{culture}/{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            constraints: new { culture = new CultureConstraint(defaultCulture: "en", pattern: "[a-z]{2}") },
            namespaces: new string[] { "Locator.Areas.Location.Controllers" }
        ).DataTokens["area"] = "Location";

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { culture = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "Locator.Areas.Location.Controllers" }
        ).DataTokens["area"] = "Location";
    }
}

请注意,这将完全替换应用程序中默认控制器的任何功能,并将所有请求发送到Location命名空间。

您应该将任何路由定义放入您的LocationAreaRegistration.cs文件中。这将确保它们是 运行 last 并且不会与您的任何其他区域路线混淆。

这里是CultureConstraint的定义。有关如何本地化路线的更多详细信息,请参阅

using System.Text.RegularExpressions;
using System.Web;
using System.Web.Routing;

public class CultureConstraint : IRouteConstraint
{
    private readonly string defaultCulture;
    private readonly string pattern;

    public CultureConstraint(string defaultCulture, string pattern)
    {
        this.defaultCulture = defaultCulture;
        this.pattern = pattern;
    }

    public bool Match(
        HttpContextBase httpContext, 
        Route route, 
        string parameterName, 
        RouteValueDictionary values, 
        RouteDirection routeDirection)
    {
        if (routeDirection == RouteDirection.UrlGeneration && 
            this.defaultCulture.Equals(values[parameterName]))
        {
            return false;
        }
        else
        {
            return Regex.IsMatch((string)values[parameterName], "^" + pattern + "$");
        }
    }
}