加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net – 使用MVC的Attribute Routing和RouteLocalization.mvc

发布时间:2020-12-16 06:34:09 所属栏目:asp.Net 来源:网络整理
导读:我希望能够为我的网站创建一个简洁的特定于语言的默认URL,以便当有人浏览时: somesite.com 他们被重定向到语言文化页面,例如: somesite.com/en-US/ somesite.com/sp-MX/ somesite.com/fr-FR/ 具体来说,我不希望/ Home / Index附加到URL: somesite.com/en-
我希望能够为我的网站创建一个简洁的特定于语言的默认URL,以便当有人浏览时:

somesite.com

他们被重定向到语言文化页面,例如:

> somesite.com/en-US/
> somesite.com/sp-MX/
> somesite.com/fr-FR/

具体来说,我不希望/ Home / Index附加到URL:

> somesite.com/en-US/Home/Index
> somesite.com/sp-MX/Home/Index
> somesite.com/fr-FR/Home/Index

我致力于使用RouteLocalization.mvc创建此站点

> Dresel/RouteLocalization
> Translating Your ASP.NET MVC Routes

我想在可行的范围内使用MVC属性路由.

我无法弄清楚如何使Start()方法重定向到特定于语言文化的URL而不添加像“index”这样的东西.

我试图遵循的样本:

using RouteLocalization.Mvc;
using RouteLocalization.Mvc.Extensions;
using RouteLocalization.Mvc.Setup;

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.Clear();

        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapMvcAttributeRoutes(Localization.LocalizationDirectRouteProvider);

        const string en = "en-us";
        ISet<string> acceptedCultures = new HashSet<string>() { en,"de","fr","es","it" };

        routes.Localization(configuration =>
        {
            configuration.DefaultCulture = en;
            configuration.AcceptedCultures = acceptedCultures;
            configuration.AttributeRouteProcessing = AttributeRouteProcessing.AddAsNeutralAndDefaultCultureRoute;
            configuration.AddCultureAsRoutePrefix = true;
            configuration.AddTranslationToSimiliarUrls = true;
        }).TranslateInitialAttributeRoutes().Translate(localization =>
        {
            localization.AddRoutesTranslation();
        });

        CultureSensitiveHttpModule.GetCultureFromHttpContextDelegate = Localization.DetectCultureFromBrowserUserLanguages(acceptedCultures,en);

        var defaultCulture = System.Threading.Thread.CurrentThread.CurrentUICulture.Name;

        routes.MapRoute(
            name: "DefaultLocalized",url: "{culture}/{controller}/{action}/{id}",constraints: new { culture = @"(w{2})|(w{2}-w{2})" },defaults: new { culture = defaultCulture,controller = "Home",action = "Index",id = UrlParameter.Optional }
        );

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

和我的家庭控制器:

public class HomeController : Controller
{
    [HttpGet]
    [Route]
    public RedirectToRouteResult Start()
    {
        return RedirectToAction("Home",new { culture = Thread.CurrentThread.CurrentCulture.Name });
    }

    [Route("Index",Name = "Home.Index")]
    public ActionResult Index()
    {
        return View();
    }

    public ActionResult Contact()
    {
        return View();
    }

    public ActionResult About()
    {
        return View();
    }
}

我的Global.asax文件:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {            
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        AreaRegistration.RegisterAllAreas();
    }
}

解决方法

重定向是一个单独的问题而不是路由.由于您将任何URL重定向到其本地化对象的目标是一个跨领域的问题,因此您最好的选择是制作全局过滤器.

public class RedirectToUserLanguageFilter : IActionFilter
{
    private readonly string defaultCulture;
    private readonly IEnumerable<string> supportedCultures;

    public RedirectToUserLanguageFilter(string defaultCulture,IEnumerable<string> supportedCultures)
    {
        if (string.IsNullOrEmpty(defaultCulture))
            throw new ArgumentNullException("defaultCulture");
        if (supportedCultures == null || !supportedCultures.Any())
            throw new ArgumentNullException("supportedCultures");

        this.defaultCulture = defaultCulture;
        this.supportedCultures = supportedCultures;
    }

    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var routeValues = filterContext.RequestContext.RouteData.Values;

        // If there is no value for culture,redirect
        if (routeValues != null && !routeValues.ContainsKey("culture"))
        {
            string culture = this.defaultCulture;
            var userLanguages = filterContext.HttpContext.Request.UserLanguages;
            if (userLanguages.Length > 0)
            {
                foreach (string language in userLanguages.SelectMany(x => x.Split(';')))
                {
                    // Check whether language is supported before setting it.
                    if (supportedCultures.Contains(language))
                    {
                        culture = language;
                        break;
                    }
                }
            }

            // Add the culture to the route values
            routeValues.Add("culture",culture);

            filterContext.Result = new RedirectToRouteResult(routeValues);
        }
    }

    public void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // Do nothing
    }
}

用法

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        filters.Add(new RedirectToUserLanguageFilter("en",new string[] { "en","it" }));
        filters.Add(new HandleErrorAttribute());
    }
}

另请注意,您的路由配置错误.每个应用程序启动时路由设置运行一次,因此将默认文化设置为当前线程的文化是没有意义的.实际上,您不应该为您的文化路径设置默认文化,因为您希望它丢失,因此如果没有设置文化,您的默认路由将会执行.

routes.MapRoute(
    name: "DefaultLocalized",id = UrlParameter.Optional }
);

routes.MapRoute(
    name: "Default",id = UrlParameter.Optional }
);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读