pre-追加如果没有可用路由 [英] Pre-Append Route if not available

查看:121
本文介绍了pre-追加如果没有可用路由的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们已经实现了一个ASP.NET MVC的网站具有URL结构如下的本地化版本:

We have implemented a localized version of an ASP.NET MVC website which has a URL structure as following:

网址:// {语言} - {文化} / {控制器} / {行动} / {ID}

url://{language}-{culture}/{controller}/{action}/{id}

在这种方式,我们可以通过生成的URL语言这是正确的由谷歌漫游器抓取:

In this way we can generate URLs by language which are properly crawled by Google bot:


  1. 的http://本地主机/ EN-US /主页

  2. 的http://本地主机/ FR-FR /主页

  1. http://localhost/en-US/Home
  2. http://localhost/fr-FR/Home

翻译是在两个地方实现。首先,我们改良的MVC的默认路由与此一:

The translation is achieved in two places. First we modified the default route of MVC with this one:

routes.MapRoute(
    name: "Default",
    url: "{language}-{culture}/{controller}/{action}/{id}",
    defaults: new
    {
        controller = "Home", 
        action = "Index", 
        id = UrlParameter.Optional,
        language = "en",
        culture = "US"
    }
);

然后,我们已经创建了一个动作过滤器,切换到当前的语言提供了URL,如果不提供给默认的:

Then we have created an action filter which switch to the current language available in the URL and if not available to the default one:

   public class LocalizationAttribute : ActionFilterAttribute
    {        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {

            string language = (string)filterContext.RouteData.Values["language"] ?? "en";
            string culture = (string)filterContext.RouteData.Values["culture"] ?? "US";

            Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));
            Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));

        }
    }
}

//本地主机/无论:

如果用户输入 HTTP出现问题。 ASP.NET MVC返回路径未找到。我怎么能传递一个默认参数的语言,如果用户忘记传递一个?我虽然通过设置的默认值到路由配置就足够了,但它不工作

The problem occurs if a user enter http://localhost/Whatever. ASP.NET MVC returns "Route not found". How can I pass a default parameter for the language if the user forgets to pass one? I though that by setting the default value into route config would be enough, but it doesn't work

推荐答案

您只需要另一条路线在没有第一部分处理的情况。

You just need another route to handle the case where there is no first segment.

routes.MapRoute(
    name: "Default-Localized",
    url: "{language}-{culture}/{controller}/{action}/{id}",
    defaults: new
    {
        controller = "Home", 
        action = "Index", 
        id = UrlParameter.Optional
    }
);

routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new
    {
        language = "en",
        culture = "US",
        controller = "Home", 
        action = "Index", 
        id = UrlParameter.Optional
    }
);

匹配的URL模式和建设的路径值集合(基于违约或可以覆盖他们的占位符)是由路线类处理2个不同的步骤。填充路由值不会发生,除非URL模式首先匹配。

Matching the URL pattern and building the route values collection (based on defaults or the placeholders that can override them) are 2 different steps that are handled by the Route class. Populating route values doesn't happen unless the URL pattern matches first.

请注意,如果您使用动作过滤器来设置当前线程的区域设置<一个href=\"http://stackoverflow.com/questions/13445278/change-culture-before-modelbinder-is-used\">localization将不可用模型绑定内。周围的一种方法是使用个IAuthorizationFilter 而不是 ActionFilterAttribute

Do note that if you use an action filter to set the locale of the current thread that localization won't be available inside of the model binder. A way around that is to use an IAuthorizationFilter instead of ActionFilterAttribute.

using System.Globalization;
using System.Threading;
using System.Web.Mvc;

public class LocalizationFilter : IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        var values = filterContext.RouteData.Values;

        string language = (string)values["language"] ?? "en";
        string culture = (string)values["culture"] ?? "US";

        CultureInfo ci= CultureInfo.GetCultureInfo(string.Format("{0}-{1}", language, culture));

        Thread.CurrentThread.CurrentCulture = ci;
        Thread.CurrentThread.CurrentUICulture = ci;
    }
}

然后将其添加为全局筛选器。

And then add it as a global filter.

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new LocalizationFilter());
        filters.Add(new HandleErrorAttribute());
    }
}

这篇关于pre-追加如果没有可用路由的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆