简介:我目前在ASP.NET Core 2.1中使用视图本地化来获取视图。作为CultureProvider
,我只使用CookieRequestCultureProvider.
然后,我需要动态更改请求的区域性,因此我将cookie重置为新值。但是,当未选择正确的请求区域时,我会遇到一个错误。
用例:我有一条路线/project/{city-name}
-行动方法Project
,路线参数为city-name
。每个项目可以具有不同数量的可能语言。因此,当一个项目中的cookie设置为另一个项目中不存在的语言时,我需要将cookie重置为另一个项目的默认值(此类信息存储在数据库中)。
因此,让我们想象一下以下情形,您访问路径/project/krakow
,然后将语言首选项设置为波兰语,因此请求区域设置为波兰语。然后,您决定转到另一个项目-project/ostrava
,该项目的语言首选项“波兰语”不存在。
因此,我需要将Cookie重置为给定项目的默认语言,以便视图本地化可以选择正确的.resx
文件。
但是,如果我重新编辑cookie,即使已设置cookie,也不会选择正确的.resx文件。只有页面刷新才能确保选择了正确的.resx
文件。
为什么会发生这种现象?为什么在呈现视图之前未设置cookie?
为了确保在呈现视图之前设置cookie,我创建了自定义中间件,该中间件对以/ project开头的路径做出反应。当我在调试器中检查cookie时,我看到已设置cookie。但是,仅在刷新页面后通知更改。
设置请求区域性的方法(为简化起见,为代码缩写)
[HttpGet]
public IActionResult SetLanguage(string culture, string city)
{
if (HttpContext.Features.Get<ITrackingConsentFeature>().CanTrack)
{
Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1), Secure = true });
}
return RedirectToAction("Project", new { City = city });
}
Cookie中间件
当我检查调试器时,我看到cookie设置正确。即使在浏览器中,我也看到已进行更改。
public class CookieMiddleware
{
private readonly RequestDelegate _next;
public CookieMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
if (httpContext.Request.Path.StartsWithSegments(new PathString("/project")))
{
var cityName = httpContext.Request.GetUri().Segments[2];
if (!string.IsNullOrWhiteSpace(cityName))
{
var unitOfWork = httpContext.RequestServices.GetService(typeof(IUnitOfWork)) as IUnitOfWork;
var projectInfo = unitOfWork.ProjectRepository.GetProjectInfo(cityName);
httpContext.Response.Cookies.Append(
CookieRequestCultureProvider.DefaultCookieName,
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(projectInfo.DefaultLanguageCode.ToLower())),
new CookieOptions { Expires = DateTimeOffset.UtcNow.AddYears(1), Secure = true });
}
}
return _next(httpContext);
}
负责选择项目视图的动作方法
[HttpGet("/[action]/{city:required}")]
public IActionResult Project(string city)
{
//HERE IN RQF I DO NOT DETECT THAT CHANGE HAS BEEN MADE.
//ONLY WHEN I DO REFRESH OF A PAGE, I SEE CORRECT REQUEST CULTURE COOKIE
var rqf = Request.HttpContext.Features.Get<IRequestCultureFeature>();
return View();
}
已注册中间件的顺序:
语言Cookie中间件在RequestLocalization之后立即注册。我什至尝试交换这两个...没有成功。
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseRequestLocalization();
app.UseCookieLanguageMiddleware(); // My cookie middleware
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}