NET8中PageRouteModelConvention添加URL文化引发重复请求及TempData丢失问题
解决.NET 8 Razor Pages中TempData因文化重定向丢失的问题
问题根源
你的问题出在两次GET请求的触发逻辑:
- Create页面Post后重定向到Edit页面时,返回的URL未包含文化参数(如
/person/edit/1) - RequestLocalization中间件检测到请求URL缺少当前用户的文化标识,自动发起第二次重定向,补全文化参数(如
/fr/person/edit/1) - TempData的机制是读取后标记删除,第一次无文化的请求已经读取并标记了TempData,第二次请求到来时TempData已被清空,导致消息无法显示;同时两次请求也触发了两次数据库操作。
管道层面解决方案(无需修改页面处理器)
方案1:全局过滤器自动附加文化参数
创建一个全局结果过滤器,在所有RedirectToPageResult重定向时自动添加当前请求的文化参数:
public class CultureRedirectFilter : IResultFilter { private readonly IHttpContextAccessor _httpContextAccessor; public CultureRedirectFilter(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } public void OnResultExecuting(ResultExecutingContext context) { if (context.Result is RedirectToPageResult redirectResult) { var requestCulture = _httpContextAccessor.HttpContext.Features.Get<IRequestCultureFeature>(); var cultureName = requestCulture?.RequestCulture.Culture.Name; if (!string.IsNullOrEmpty(cultureName) && !redirectResult.RouteValues.ContainsKey("culture")) { redirectResult.RouteValues.Add("culture", cultureName); } } } public void OnResultExecuted(ResultExecutedContext context) { // 无需额外处理 } }
在Razor Pages服务注册时添加这个全局过滤器:
services.AddRazorPages(options => { options.Conventions.Add(new CultureTemplateRouteModelConvention()); options.Filters.Add<CultureRedirectFilter>(); // 注册全局过滤器 }) .AddDataAnnotationsLocalization(options => { options.DataAnnotationLocalizerProvider = (type, factory) => { var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName); return factory.Create(nameof(SharedResource), assemblyName.Name); }; }) .AddViewComponentsAsServices() .AddRazorRuntimeCompilation();
方案2:禁用RequestLocalization自动重定向(不推荐)
如果业务允许URL不强制携带文化参数,可以修改RequestLocalizationOptions,关闭自动补全文化的重定向行为:
services.Configure<RequestLocalizationOptions>(options => { // 配置支持的文化列表 var supportedCultures = new[] { "en", "fr" }; options.DefaultRequestCulture = new RequestCulture("en"); options.SupportedCultures = supportedCultures.Select(c => new CultureInfo(c)).ToList(); options.SupportedUICultures = options.SupportedCultures; // 使用自定义文化提供器,跳过自动重定向逻辑 options.AddInitialRequestCultureProvider(new CustomRequestCultureProvider(async context => { // 示例:从Cookie读取用户选择的文化,无Cookie则用默认值 var cultureCookie = context.Request.Cookies["UserCulture"]; var targetCulture = string.IsNullOrEmpty(cultureCookie) ? "en" : cultureCookie; return await Task.FromResult(new ProviderCultureResult(targetCulture)); })); });
注意:此方案会让URL始终不带文化参数,若你的业务依赖URL中的文化标识,优先选择方案1。
效果验证
使用方案1后,RedirectToPage("./Edit", new { Person.Id })会自动生成带文化参数的URL(如/fr/person/edit/1),避免了两次重定向:
- TempData只会在最终的Edit页面请求中被读取,消息正常显示
- 数据库仅收到一次请求
内容的提问来源于stack exchange,提问作者Steven Bitaxi
相关产品推荐
相关产品推荐

