Required for model but initially empty field for View - MVVM - c#

please help me with this:
I have model with property of Enum type. This property is required, but on View initial value must be empty. Will show watermark..
If I understand correct than model will have not nullable property. But viewModel will have nullable. Is this right way?
Looks like in this case:
need create viewModel
viewModel and model will have different data sometimes
viewModel need logic for set and get correct values to/from model or get null in first time and leave as is model
viewModel need one more validation rule
Other way is:
Model will have nullable property and required validation:
can bind to model
model does not "correspond to reality"
we need always expose data from nullable enum and forgot about null? or handle it (convert to DTO or something like this)
nullable property is only UI requirement and can be changed in future

Having the (domain) model use a non-nullable enum suggest that the value MUST have a valid value for use case and / or data integrity.
Having the requirement on the UI to allow a non-valid value (initial or otherwise) will result in 1 of 2 things:
When the View posts a null value (via a dedicated ViewModel) and checks are performed to ensure its not null (I assume that the user selects the "Please Select" value from a select box) the server will respond with an error message saying something like "Please select a valid value blah blah".
Or, the server will allow the null from the View Model and default the domain model property to some predetermined sensible value.
In my experience this kind of setup leads to a frustrating user experience because having the UI present an invalid selection option that only feedsback upon submit (or using some frontend / client validation) is rather annoying (especially on a long form, Etc).
Perhaps you would be better rethinking that requirement so the UI only presents valid enum values for selection and optionally make the default one a sensible value.
Having said that if you really want the UI to not have a valid initial value then make a view model with a nullable version and validate on the server as you suggest. As far as changing the (domain) model with a nullable, you already seem concerned that it doesn't "correspond to reality" which is a good impulse considering you already mentioned that this is a UI only requirement, thus place the detail in that layer and keep your domain modals as close to reality as is needed to satisfy your use cases and / or business requirements.

Related

Model Binding vs Form Collection, performance, scalability, change, etc.? [duplicate]

I've inherited a code base written in ASP.Net MVC 4. Every post method takes a FormCollection. Aside from annoyance of having to access the values through quoted strings, it also leads to drawbacks such as not being able to use things like ModelState.IsValid, or [AllowHtml] attributes on my ViewModel properties. They actually did create ViewModel classes for each of their views, (though they are pretty much just direct wrappers around the actual Entity Framework Model classes), but they are only used for the GET methods.
Is there anything I'm missing about FormCollection that gives a reason why this may have actually been a good idea? It seems to only have drawbacks. I'd like to go through and "fix" it by using ViewModels instead. This would take a good bit of work because the ViewModels have properties that are interfaces and not concrete classes, which means either writing a custom binder or changing the ViewModels.
But perhaps there's something I'm missing where it makes sense to use FormCollection?
Is there any good reason to use FormCollection instead of ViewModel?
No. I have following issues.
Issue - 1
In case FormCollection is being used...It will be mandatory to Type Cast the Primitive Type Values un-necessarily because while getting the entry of specific Index of the System.Collections.Specialized.NameValueCollection, value being returned is of type String. This situation will not come in case of Strongly Typed View-Models.
Issue - 2
When you submit the form and goes to Post Action Method, and View-Model as Parameter exists in the Action method, you have the provision to send back the Posted Values to you View. Otherwise, write the code again to send back via TempData/ViewData/ViewBag
View-Models are normal classes, created to bind data to-from Views
Issue - 3
We have Data Annotations that can be implemented in View Model or Custom Validations.
ASP.Net MVC simplifies model validatons using Data Annotation. Data Annotations are attributes thyat are applied over properties. We can create custom validation Attribute by inheriting the built-in Validation Attribute class.
Issue - 4
Example you have the following HTML
<input type="text" name="textBox1" value="harsha" customAttr1 = "MyValue" />
Question : How can we access the value of customAttr1 from the above eg from inside the controller
Answer : When a form get posted only the name and value of elements are posted back to the server.
Alternatives : Use a bit of jQuery to get the custom attribute values, and post that along with the form values to action method
Another option is to rather put what you got in your custom attributes in hidden controls
That's the reason, I would always prefer to use View-Models
The only advantage I can think of is if you want to use the automatically generated controller provided when you don't specify a EF model to be strongly typed to. In that case, your Create and Edit actions will use the FormCollection object as it is a reliable, pre-existing artifact of the framework to work with for this purpose. Perhaps the previous developer chose this option while creating his controllers, and stuck with it since Visual Studio must know what it's doing :)
But, in reality, I would never recommend this headstart of a few seconds. It's always better to build out viewmodels, I would recommend looking at the effort to move in that direction if only for maintenance purposes. With model binding and strongly typed views and html helpers, you are much more likely to reduce the number of run-time errors as a result of changing some magic string and not realizing it until your page blows up.
Ok, I see the general consensus here is that it isn't liked. To offer another perspective, I've always liked using the formcollection passed into the controller on POST actions. It offers the use of the TryUpdateModel method from the controller which will map the collection to your strongly typed class. TryUpdateModel also has overloads that allow you to white list the properties of the model that you want to allow to be updated.
if (TryUpdateModel(viewModel, new string[] { "Name" }))
{
//Do something
}
It still allows all the model binding you want, but helps to keep anything other than the "Name" property on my viewmodel from being updated.
You can see more about the TryUpdateModel method here:
http://msdn.microsoft.com/en-us/library/system.web.mvc.controller.tryupdatemodel(v=vs.108).aspx
There are always workarounds for getting away from a FormCollection lol.. you can have hidden fields bound to your view model variables in the form to your heart's content.
Form collections mostly emerge from the laziness of creating a view model but still end up taking time trying to get figure out how to get the values out of it in your controller :P
I think it was simply created in the very beginning of MVC as an alternative to using strongly typed views when having very simple forms - back in the days when everyone used ViewBag :) ... and once hey had it in there they couldn't just take it out as simple as that.
Maybe you can use it if you are absolutely sure your view will never have more than one form input? Probably still a bad idea though..
I cant find any recent articles talking about any advantages of form collections.. while strongly typed views are everywhere.
Yes. Sometimes, it can be useful. Here's an example:
Let's say we have in our db "date_and_time_field".
In Razor View, we want to use two form fields. The first one "Date" (maybe with jQuery UI Datepicker). The second one "Hour".
In the Controller Action, we compose the "date_and_time_field" by means of Request.Form["Date"] and Request.Form["Hour"].
There are other scenarios where it can be useful:
A cross-table (with checkBoxes in Razor view)
The collection Request.Unvalidated().Form (maybe this is not part of your question: I don't wanna be off-topic)
The default model binder will do almost everything you need it to do. I resorted to the FormCollection once - only to later figure out how to bind arrays of elements into a collection on the ViewModel.
Just go ViewModel. Better all around, for every reason enumerated.
With form collection you will be able to get all the values inside the form. There can be situations where you may need to pass some additional values from the form which may not be part of your view model.
Just take an example of passing 10 hidden values from the form. The form collection makes sense.
The only difficulty that you may face is type casting. All form collection items that you get will be string; you may need to type cast based on your requirement.
Also model state validation is another area where you may face a challenge.
You can always add the form collection properties to your method signatures. They will automatically be populated by form values with corresponding keys.
Well with Forms Collection you will find a quick way to get the values of a form. Otherwise you have to create a class that mimics the Form Fields and people are sometime lazy to create custom classes for less important/rarely used Forms.
No there is no extra benefit (in fact limited) of forms collection over a custom class as action parameters and it should be avoided whenever possible.
Responding to the title question: yes.
There are some situations that FormCollection needs to be used. For instance, suppose a ViewModel that has a property that implements the 1 to N relation (in concrete case, a TimesheetViewModel with ICollection<TimesheetEntryViewModel>), and the Controller has to perform a validation between the time entries to not get a time collision between the end time of an entry and the start time of the following entry. To mark a related entry with a validation error, how can be the line index be retrieved?
Well, with the default model binding, the index value is lost in the Controller logic. Fortunately, FormController stores the index you used in the View and a more specific validation can be done.
There are type of SPA apps where you have no idea about your model (there is no ViewModel at all and views are created dynamically (for short ;))), so FormCollection is your only choice where you implement custom post validation having entire page input values...
If your view has a knowledge about the model then, of course, you can use your concrete ViewModel object. That's easy ;)

Specify that model binder must use specific value provider for a property

This is more of a curiosity for me than something I actually need to do. Is there a way to tell the model binder that it should only attempt to find a value using a specific IValueProvider?
ie: Let's say I have a model whose Id property I want to be bound specifically from the QueryStringValueProvider. The way the default value provider works is a first-with-value-wins situation. So if I have a value provider registered before the QueryStringValueProvider, and that provider returns a value first, then the query string value is ignored entirely.
I know I can make a custom ModelBinder and deal with it that way, but I'm wondering if there's a built in way of handling this already(like popping an attribute on the property or something)?

How to differentiate between user specified null and default value in WCF data contract

I need to define a WCF API to enable user to update large object. While I can define few smaller methods and let the user update specific parts of the large object at a time. But for some reason I am not able to do that. The other way I tried is defined the data contract as collection of key-value (key is an enum and value is some string) and let the user add whatever he wants to update. This api very compact but it's not very intuitive and can be confusing for the user. Also since the value is of string type, so it's not very type safe.
So I now I have create one api, where the user can update the entire object.
for example:
public UpdateResult UpdateAPI(UpdateParam param){}
Now the UpdateParam class will several nullable fields.
Q: If there is a null value in one of the fields, how can differentiate at the server side,
the null value was specified by the user or it's default non-specified one? Is there something in the incoming soap message that can help differentiate?
Any help would be greatly appreciated.
Similar questions asked are
1. Data member default values, how to figure out whether something was really sent?
2.
no, as far as i know there is no way to tell the conditions apart if you only have a nullable field ...
however, you could provide an additional bool per property that could serve as a flag to indicate if the value was set by the user or is still on its default value
You can implement the setters of your properties to automatically set the corresponding bool when your properties are set

How to detect if form field has changed without using hidden field

I am using ASP.NET MVC 3 and have a need to detect if the form field has been changed on the server side. I know about using tricks with hidden fields, but I was wondering if there is a way to do it by just using the API?
Basically, I have edit screen for my model and one of the fields is an optional id that can be specified. If the field is specified, I have to insure it is unique (no other model has it). So on the edit controller, I want to run the validation but only if that field has been changed.
Please note, I don't need to know previous value vs. new value, just if the field value has changed.
You will have to keep a copy of the old value somewhere, and do the comparison. You may store it in your View Model.
There is indeed no 'dirty' flag - MVC actually is closer to "the way the web works" to reuse that statement. All that is sent over are name value pairs. nothing else. MVC's model binder just matches those names to your object - so in order to truly detect a change you have to either validate against the true data source upon post or compare values passed in on the form - in which case - it is best to hash to avoid forgery.

Is applying default values to properties good or bad practice?

Is it good or bad practice to apply System.ComponentModel.DefaultValue default values to my properties? What about my ViewModel properties?
I ask because I'm passing a ViewModel into my Controller. This ViewModel contains properties such as OrderByColumn, SortDirection and PageSize. When the page first loads, these need to be set to something.
If you are comfortable setting these values in your ViewModel then it should be ok. I do this for setting SelectLists that are tied to Enumerations on my view. As long as these are defaults for the particular View. If these are more wide sweeping I would suggest building some kind of convention to set them inside your controller.
System.ComponentModel.DefaultValue does not help you in that case.
It is designed to set only default values for properties in designer.
Check this: http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx
If you need to set default values to your model you have at least two another options:
1) you may set default values in constructor
2) directly in controller, in that case you may check if e.g OrderByColumn == null then assign default value.
First off DefaultValue does nothing by itself and you'll have to invoke the default values via reflection. A better thing to do is use the ViewModels constructor to set these default values.
As far as default values go, sometimes null doesn't cut it, and you need to have them. This is totally dependent on your requirements though.

Categories