【发布时间】:2018-02-16 21:19:54
【问题描述】:
这似乎是关于文化或路线的任何其他问题,但我无法弄清楚为什么会发生这种情况。
当我尝试在未经身份验证的情况下访问 [Authorize] 元素时,我会被重定向到登录页面,并在查询字符串中使用 ReturnUrl 参数。那很完美。 (样板应用)
现在我的问题是:如果我对 url 中的本地化(来自 routeConfig)执行相同的操作,即:url: "{lang}/{controller}/{action}",我将使用此参数第一次被重定向,但在被传递之后通过 将我重定向到本地化路线的基本控制器。之后,在加载登录页面 (.cshtml) 时 ReturnUrl 为 null...
我查看了很多文章,并尝试了许多技巧/选项,也许在我做的事情破坏了一切的过程中,所以这里有一些代码:
第一个路由配置:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "LocalizedDefault",
url: "{lang}/{controller}/{action}",
defaults: new { lang = UrlParameter.Optional, controller = "Home", action = "Index" } ,
constraints: new { lang = "fr-CA|en-US" }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
在 BaseController 中:
protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
{
string cultureName = RouteData.Values["lang"] as string;
// Attempt to read the culture cookie from Request
if (cultureName == null)
{
cultureName = Request.UserLanguages != null &&
Request.UserLanguages.Length > 0 ?
Request.UserLanguages[0] :
null; // obtain it from HTTP header AcceptLanguages
}
// Validate culture name
cultureName = CultureHelper.GetImplementedCulture(StartupMVC.SupportedLangs, cultureName);
if (RouteData.Values["lang"] as string != cultureName)
{
// Force a valid culture in the URL
RouteData.Values["lang"] = cultureName.ToLowerInvariant(); // lower case too
// Redirect user
//Response.SuppressFormsAuthenticationRedirect = false;
****HERE**** if I comment this line, I keep returnUrl but my route is like {controller}/{action}/{id} => So default language Response.RedirectToRoute(RouteData.Values); otherwise route ok {lang}/{controller}/{action}/{id} but no ReturnUrl
}
SetCurrentCultureOnThread(cultureName);
return base.BeginExecuteCore(callback, state);
}
还有一点 Login.cshtml:
@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
...
}
我希望这很愚蠢,您可以向我指出一些明显的解决方案。 否则,有人明白吗?或许能帮我解决它?
PS:如果我不够清楚或者您需要更多信息,请评论您需要什么! :)
编辑:来自 NightOwl888 的评论,我想补充一些问题:
_我知道至少有 3 种处理本地化的主要方法(查询字符串中的语言环境、路由中的区域设置、翻译 url),但是是否有任何关于本地化和文化的记录或常用的最佳实践?
_.NET 框架如何处理重定向到登录以及它如何处理查询字符串? (因为我们不能用查询字符串值注册路由)
【问题讨论】:
-
这种方法的问题太多,这里就不一一列举了。请参阅ASP.NET MVC 5 culture in route and url 并确保阅读有关将用户自动重定向到他们的文化的 cmets。
-
感谢您的评论。我看到了这个答案,我认为对于现在必须广泛使用的东西来说它有点复杂......因为你似乎对这个主题了解很多,我很想知道更多,我会补充我的问题一些额外的问题,因为它可能对其他人很有价值。
-
MVC 没有内置任何东西可以让它跳过本地化的路由并转到非本地化的路由(不诉诸 302 重定向)。事实上,根本没有用于 URL 本地化的内置扩展 - 唯一的选择是自定义或使用第 3 方。但是,我不能强调让请求一直到控制器然后重定向到另一个控制器是多么糟糕。重定向有一个的目的 - 更改浏览器中的 URL。路由的目的是让第一个请求直接发送到正确的控制器,无需第二个请求。
-
顺便说一句 - 上面的链接是我对 SO 的最高投票答案。它不是那样的,因为它对人们来说太复杂了。它实际上是复制、粘贴和配置的 2 个类,以及对视图的一些修改,以允许用户切换文化。只有在需要本地化属性路由时才需要属性路由代码。
标签: asp.net-mvc asp.net-mvc-5 culture redirecttoroute