Reputation: 30013
As far as I can tell, there's a bit of a problem with ASP.NET's ModelState mechanism. It only stays around for the context of the current HTTP request. So let's say I just want to use server-side validation. I can write this in my .cshtml
view:
@using (Html.BeginForm("Index", "MyController", routeValues: new { Area = "MyArea" }, method: FormMethod.Post, htmlAttributes: new { @autocomplete = "off" }))
{
@Html.TextBoxFor(m => m.SomeTextbox, new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.SomeTextbox)
...
... where my model is:
public class SomeModel
{
[Display(Name = "Some Textbox")]
[Required]
public string SomeTextbox { get; set; }
If I now check for model state validity in my action method, the validation message ("The Basic Textbox field is required.") is correctly displayed by the ValidationMessageFor
helper when I submit the form with no content in the textbox:
public class MyController : Controller
{
[HttpGet]
public ActionResult Index()
{
return View(new SomeModel());
}
[HttpPost]
public ActionResult Index(SomeModel model)
{
if (!ModelState.IsValid)
{
// Server-side model validation failed; abort!
return View(model);
}
...
However, this stops working if, instead of POSTing to /Index
, I POST to something like /Update
and then do a redirect back to /Index
if there's an error in the model. This is because ModelState only lasts for the current HTTP request context, and ValidationMessageFor
relies on ModelState to get its error messages. When you redirect back to /Index
, this state is lost.
This is exactly what TempData
was designed to get around, as it keeps its session state until it is read in a later HTTP request. However, ModelState doesn't seem to use a mechanism like this.
Is there a way to have ModelState use some mechanism like TempData
so that if I POST to a different URL and redirect back upon an invalid model state, I correctly get the error messages rendered to the page using ValidationMessageFor
(and, more generally, I retain the ModelState from the form submission before I redirected)?
Upvotes: 1
Views: 1007
Reputation: 30013
OK so basically I've found out that what I was describing was the PRG model, which isn't usually used in ASP.NET. You usually POST back to the same URL and so you have the HTTP context in which you POSTed, and only redirect in the case of a success in which case you no longer need the ModelState. People have come up with workarounds to implement PRG in ASP.NET, though, such as:
https://andrewlock.net/post-redirect-get-using-tempdata-in-asp-net-core/
Upvotes: 1