MVC3-ValidationFailure-RetainValues - asp.net-mvc-3

I am using MVC3 in ASP.NET. In the Post Action,
I have an View, In which it should let me edit the values. Some fields are read-only and some fields are editable. If there is a validation failure then it should retain the values and display the same View, if there are no error then it should let me to submit the form.
Control1:
Name I have to display as label as It has to be read-only
#Html.DisplayFor(Model => Model.Absentee.Name)
Control2:
I have to display this one as textbox so that it can be edited. This is a required Field.
#Html.TextBoxFor(Model => Model.AbsStart)
#Html.ValidationMessageFor(Model => Model.AbsStart) (This Makes it as a required Field)
Control 3:
This is also a textbox but not required field.
#Html.DisplayFor(Model => Model.AbsEnteredAt)
When there are no validation errors, things works great, but when there is a validation error, then I will be in the same view(Which is what I want) but the value in First control is not retained.
So Basically, when the validation failure, the value is not retained in the DisplayFor Control
What do I do to sort this?
Thank you

As 99% of my answers in the asp.net-mvc tag this one is the same: USE VIEW MODELS. Don't have your controller actions take/pass domain models to/from views. Design view models for each view. View models are classes which are specifically tailored to meet the requirements of this given view. So let's suppose that you have two different views which allow you to edit/update the same domain model. Then you will design two different view models and each view model will contain only the properties that are used by the respective view along with their specific validation requirements.
As far as the DisplatFor helper is concerned, it generates a simple label. Labels are never sent to the server when you submit a form. So you can hope to populate/validate on your controller action only the properties that are contained on the form. For properties that should not be displayed you could use either hidden fields or a single hidden field containing only some unique identifier so that you can fetch from your datastore back the original values (as the user is not supposed to modify them anyways).
As far as the mapping between the view model that you should design and the original domain model is concerned, this mapping is usually performed inside the controller and to simplify it I would recommend you to use AutoMapper.

When there is an error, what is the viewModel you are returning? DisplayFor does not get sent back to the server ... add this under the displayfor:
#Html.HiddenFor(Model => Model.Absentee.Name)

Related

MVC 3 Razor-Partial Validation of Model

I am currently working on a project in MVC 3 where I am leveraging Entity Framework to persist one data model over two Views which each contain one HTML Form (similar to wizard-based design).
Yet after the user fills out the appropriate fields on the first View and submits the form, client-side validation for the entire model is triggered, and validation errors are shown for fields that will not even be available for input until the second View instantiates.
I have currently implemented a workaround where I simply turn off client-side validation for the first View entirely, but I am certainly not keen on the idea of populating my model with data that has not been validated at all. This is bad. M'kay.
Is there any way to partially validate the fields on the first View and not trigger valdiation for the whole data model?
That's where ViewModels comes. Instead of directly binding the domain model with the views, you should create view models over them and bind to the views.
If you are not required to put validation on the EF models directly then you can use the MetadataType to do partial validation as needed. Take a look at my long example here on stackoverflow.
Thanks for the input all. However, I was able to obtain a solution in a very simple way. By placing the following code in the HttpPost element of the first View...
if (ModelState.IsValidField("FirstField") && ModelState.IsValidField("SecondField"))
return RedirectToAction ("NameOfAction", model);
else
return View();
...I was able to achieve partial field validation. However, this field-specific approach will ONLY work provided the Submit button on the first View has class "cancel" and the additional validation errors that are generated (for the fields that are NOT present on the first View) are manually cleared before the above if statement. To do this, use:
ModelState["FieldName"].Errors.Clear();
No major change in architecure. No partial Views. No handing off unvalidated Data.
Works very well...
NOTE: If the second View loads with validation errors, use:
ModelState.Clear();
in the Action where the second View is initially called. This will make the second View load clean and error free, while still showing the validation errors later upon final form submission.

EditorTemplate as a dynamic form

I have a form that will load some fields when the page is requested and some other fields that will be loaded as the user choses one option in a dropdown. The fields that should be loaded upon selection are EditorTemplates. Is there a way I could make it work without the need to refresh the page (i.e a partial view requested via ajax) and keeping the "binding" to my viewmodel?
Yes, this is possible as long as you respect the naming conventions of your input fields so that the default model binder can understand them. Here's an example of those conventions for lists. And here's a great article illustrating how you could implement editing a variable length list.

Using the HTML.DropDownList helper with view model and Ajax

I'm trying to use a html.dropDownList helper with a strongly typed view model with ajax. I can't the post the code because of the nature of the project.
Here basically what I'm doing...
loading a mvc view via a strongly type view model
clicking a button which does an ajax post to a controller method
using the TryUpdateModel to parse the view model
processing the request
rendering a parital view for the ajax request
According to the article listed below, the problem is that "ASP.NET MVC assumes that if you’re rendering a View in response to an HTTP POST, and you’re using the Html Helpers, then you are most likely to be 'redisplaying a form' that has failed validation."
http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx
Instead of "redisplaying the same form value", I need the html.dropDownList to be set to the same value in the view model.
Does anyone know of any custom dropDownList helpers or have any ideas of how to achieve this?
Things I've already tried/considered
per the blog, manually removing the modelstate item...didn't work - didn't pick up the value in the view model - just defaulted to the first item in dropdown list
considered just writing a regular select list...but this is sloppy and cumbersome since I'm rending multiple select lists in a loop
writing my own custom dropDownList helper...wanted to avoid reinventing the wheel
Thanks in advance
Its not fully clear to me what your problem exactly is, but I've had a similar problem. I used the Html.DropDownListFor(, SelectListItem[]) helper. At postback it sets the value to the choosen one. Your postback view doesn't require to have all the fields of the original model.
#Html.DropDownListFor(model => model.SelectedValue, MyModels.DropDownSelectables());
Here I want the selected value as the model.SelectedValue variable and within my (seperate) model I made a array of selectlistitems. The rest is automagic.
Hope it helps, D

How to Handle Mutiple Model Bound Forms

I am buiding a UI screen for editing the details of an Ecommerce Order. The model for my view (OrderModel) has everything I need (in properties that are also ViewModels), but the UI isn't designed to be able to edit all of it at once.
For example, one part of the UI is for customer data..another for order details, and another for tracking information, each having their own "Save" buttons.
I realize that I could use one giant form and use hidden form fields to populate the non-editable fields, making each "Save" button post all the data, but that smells bad.
I'd like to segment the editable chunks into smaller ViewModels that are posted and validated individually while retaining the strong typing but I'm unsure of how to achieve this in MVC3. Will I need partial views that are called from the primary view?
FYI, I'm using ASP.NET MVC 3 with Razor syntax and client side FluentValidation.
Partial Views are a good solution. You can pass different ViewModels to each partial view. But if only sections of the overall view are updated at a time I would not do a post back on the whole page. Instead I would use Ajax calls using JQuery/Javascript to update the individual information back to the controller. I would also look into something like Knockout.js to handle the data binding on the page.

Structure for a view with an optional secondary model in MVC3

I have an MVC3 project I'm working on that has a View with an associated strongly typed view model. I've been tasked with adding an optional section to this view that would contain the data for a second model, about half of which is shared with the first model.
My question is, what is the best way to implement this? Should I just add the object that the optional model represents to the view model and try to map values from there?
If I do it this way, how can I associate the editors with both models?
Adding the optional model to the view model is the best choice, because, unlike ViewBag, it's type safe and you can still leverage the html helpers. Just remember to check the second model for null reference before you render it (since it's optional).
For sharing properties, your view model can have special getters/setters that would mantain both models synchronized internally.
I think I understand what your asking and this is how I have accomplished it in the past.
Add the optional model as a parameter in the view model and then create a partial view that is typed to that optional model. If the criteria is met that allows that partial view to display then you pass the viewmodel.optionalmodel to that partial view.
You just have to be a bit careful about the overlap of parameters causing any headaches (as in null references)

Resources