In a basic CRUD app using NET8, I noticed that TempData
, which provides the message "Person added successfully"
, was showing briefly on a page and then being cleared.
Inspecting the Network traffic on the client revealed two get requests https://host/person/edit/1
followed by https://host/fr/person/edit/1
. I confirmed in the database that two requests were being sent for the record.
The OnPost
handler for the Person/Create page redirects sets the TempData["Message"]
then redirects the user to the edit page for subsequent changes to Person:
return RedirectToPage("./Edit", new { Person.Id });
The app uses the following PageRouteModelConvention to prepend the user's selected culture (culture selector in a dropdown on the page)
public class CultureTemplateRouteModelConvention : IPageRouteModelConvention
{
public void Apply(PageRouteModel model)
{
var selectorCount = model.Selectors.Count;
for (int i = 0; i < selectorCount; i++)
{
var selector = model.Selectors[i];
model.Selectors.Add(new SelectorModel
{
AttributeRouteModel = new AttributeRouteModel
{
Order = -1,
Template = AttributeRouteModel.CombineTemplates("{culture?}", selector.AttributeRouteModel.Template),
}
});
}
}
}
It's added via convention in the services
services.AddRazorPages(options =>
{
options.Conventions.Add( new CultureTemplateRouteModelConvention() );
})
.AddDataAnnotationsLocalization(options =>
{
options.DataAnnotationLocalizerProvider = (type, factory) =>
{
var assemblyName = new AssemblyName(typeof(SharedResource).GetTypeInfo().Assembly.FullName);
return factory.Create(nameof(SharedResource), assemblyName.Name);
};
})
.AddViewComponentsAsServices()
.AddRazorRuntimeCompilation();
then configured in the Pipeline
var localizationOptions = app.Services.GetService<IOptions<RequestLocalizationOptions>>().Value;
app.UseRequestLocalization(localizationOptions);
I expect the solution is to include the Culture in the redirect to the client but I don't know how to configure that in the pipeline. I'd rather not do it in the handler.
Retrieving the culture from the client request and including it in the RedirectToPage prevents the additional request from the client.
public async Task<IActionResult> OnPostAsync(CreatePersonCommand person)
{
var result = await mediator.Send(person);
HandleResponse(result);
if (Success)
{
var rqf = Request.HttpContext.Features.Get<IRequestCultureFeature>();
var culture = rqf.RequestCulture.Culture.Name;
return RedirectToPage("./Edit", new { culture = culture, Id = result.Person.Id });
}
return Page();
}