Reputation: 4136
Our application (MVC5) has some very complex validation that needs to be done server side (compound capacity checks, workflow validation, and more). The problem we are running into is that once server side validation fails and returns to the same view, the client side never submits values for any fields again (0 for int, empty strings, etc.)
Our general pattern is as follows:
public ActionResult PerformSomeAction()
{
var model = GetActionTemplate();
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult PerformSomeAction([Bind(Include = ActionTemplate.FIELDS)] ItemTemplate template)
{
string errorMessage;
if (ModelState.IsValid)
{
bool isValid = ValidateAndPerformAction(template, out errorMessage)
if(isValid)
return RedirectToAction("Action", "Controller");
}
// Reset non-bound fields from new template
var model = GetActionTemplate();
template.FieldValue = model.FieldValue
return View(template);
}
Our views don't have anything special in them, other than the fact that some of our editors are built with the Telerik Kendo library. However, the symptoms are seen for all controls, not just Kendo based ones.
A basic View layout for editing a field is as follows:
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-3" })
<div class="col-md-9">
@Html.Kendo().TextBoxFor(model => model.Name).HtmlAttributes(new
{
title = ModelMetadata.FromLambdaExpression(model => model.Name, ViewData).Description
})
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
Does anyone have any suggestions on what we are doing wrong?
Note: While it could be argued that this validation could be triggered through AJAX or other service calls, we would prefer to do it with the post implementation that we are using.
Update: After further research, it appears this has to do with Kendo and not MVC. If I switch my View to be the following:
@Html.EditorFor(model => model.Volume)
Instead of:
@Html.Kendo().NumericTextBoxFor(model => model.Volume).HtmlAttributes(new
{
@class = "",
title = ModelMetadata.FromLambdaExpression(model => model.PreBoilVolume, ViewData).Description
}).Value(Model.Volume)
Everything appears to work fine. So somewhere in that Kendo statement it fails to rebind when returning from the post. It doesn't matter if I set the value again manually, it will never send it back in.
I guess it is time to get rid of some Kendo statements and go back to a more basic UI.
Upvotes: 0
Views: 318
Reputation: 5366
What you "want" to do is a very basic scenario for MVC with failed validation.
The first one that always catches people is with drop down lists. The posted model, does not contain the list of items, so has to be re-populated after failed validation, and then passed back into the view on return.
When I can't solve things like this I start commenting stuff out and work forwards. So in this case strip your model back to one non-ID property and see if it will work. Then you can try and track down the culprit.
Upvotes: 1
Reputation: 59
It looks like the selectedvalues are not set on the model. Try change these lines of code:
var model = GetActionTemplate();
template.FieldValue = model.FieldValue
return View(template);
to something like this:
var model = GetActionTemplate();
model.Selectedvalues = template.FieldValue ?
return View(model);
Upvotes: 0