简体   繁体   English

在MVC4中更改运行时的路由

[英]Change route on runtime in MVC4

Currently when I enter /ru/ it will change to Russian language but then if I go to / it will display Russian resources (meaning cookie/locale is set), however it won't redirect to /ru/ . 目前当我输入/ru/它将改为俄语,但如果我去/它将显示俄语资源(意味着设置cookie / locale),但它不会重定向到/ru/ I can't really just redirect it since, for example if user is on /en/item/32 and he changes language to Russian he needs to be redirected to /ru/item/32 , not /ru . 我不能真正重定向它,因为,例如,如果用户在/en/item/32并且他将语言更改为俄语,则需要将其重定向到/ru/item/32 ,而不是/ru

My [Localization] data-annotation function that checks cookies 我的[Localization]数据注释函数检查cookie

public class Localization : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (filterContext.RouteData.Values["lang"] != null && !string.IsNullOrWhiteSpace(filterContext.RouteData.Values["lang"].ToString()))
        {
            // Set from route data
            var lang = filterContext.RouteData.Values["lang"].ToString();
            Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(lang);
        }
        else
        {
            // Set from cookie
            var cookie = filterContext.HttpContext.Request.Cookies["lang"];
            var langHeader = string.Empty;
            if (cookie != null)
            {
                langHeader = cookie.Value;
                Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(langHeader);
            }
            else
            {
                // Cookie does not exist, set default
                Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-US");
            }

            filterContext.RouteData.Values["lang"] = langHeader;
        }

        // Update cookie
        HttpCookie _cookie = new HttpCookie("lang", Thread.CurrentThread.CurrentUICulture.Name);
        _cookie.Expires = DateTime.Now.AddYears(1);
        filterContext.HttpContext.Response.SetCookie(_cookie);
        base.OnActionExecuting(filterContext);
    }
}

And my routes are configured like so 我的路线配置如此

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

        routes.MapRoute(
            name: "Localization",
            url: "{lang}/{controller}/{action}/{id}",
            defaults: new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "ORMebeles.Controllers" }
        );

        /*
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
            namespaces: new string[] { "ORMebeles.Controllers" }
        );
        */
    }
}

So how can I just inject the {lang} attribute to route and make it stick there? 那么我怎样才能将{lang}属性注入路由并使其粘在那里?

The trouble you've got here is that OnActionExecuting runs after the incoming request has been evaluated against your routes. 您遇到的问题是OnActionExecuting在针对您的路由评估传入请求后运行。 So setting filterContext.RouteData.Values["lang"] = langHeader; 所以设置filterContext.RouteData.Values["lang"] = langHeader; has no effect in this scenario. 在这种情况下没有任何影响。

There's a good (MVC 2) example here of how to set up a multi-language site, although this example does not use a lang variable in the url - about halfway down they set up ActionLinks to an action that changes the culture and then redirects back to the previous page. 有一个很好的(MVC 2)例如这里的如何建立一个多语言的网站,虽然这个例子没有在网址中使用lang变量-约一半,他们成立了ActionLinks来改变文化,然后重定向动作返回上一页。

If you need to keep the lang variable in the URL, you could set up the links to point at the current page, but change the lang parameter, using an HtmlHelper like this: 如果你需要在URL中保留lang变量,你可以设置链接指向当前页面,但是使用HtmlHelper更改lang参数,如下所示:

public static MvcHtmlString ChangeLanguageLink(this HtmlHelper html, string text, string lang)
{
    var currentController = html.ViewContext.RouteData.GetRequiredString("controller");
    var currentAction = html.ViewContext.RouteData.GetRequiredString("action");

    return html.ActionLink(text, currentAction, currentController, new { lang }, null);
}

This should use your route to produce a link that sends the user to the same action but with a different lang - and your Localization filter can set the current culture accordingly. 这应该使用您的路由生成一个链接,该链接将用户发送到相同的操作但具有不同的lang - 并且您的Localization过滤器可以相应地设置当前文化。

If there is no lang specified in the url and you need to redirect, then you can set the filterContxt.Result to a RedirectResult with similar parameters as described above. 如果url中没有指定lang并且您需要重定向,则可以将filterContxt.Result设置为具有如上所述的类似参数的RedirectResult

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM