I am learning MVC, and in ASP.Net MVC 3, what is the ModelState class ? I have looked on Google and MSDN, but I can't seem to get a clear understanding of it's purpose. Can anyone help?
Take a look at http://www.gxclarke.org/2010/05/consumption-of-data-in-mvc2-views.html under the ViewData.ModelState section.
The ModelState property is a dictionary object that tracks HTTP values submitted to the server. In addition to storing the name and value of each field, it also tracks associated validation errors. Although its name may suggest otherwise, ModelState isn’t Model-aware. It doesn’t understand what a "Product" is. It simply contains a collection of items with names such as "ProductName" and "UnitPrice". It is the responsibility of other objects—ModelBinders, ViewResult, and the strongly-typed View—to map and interpret ModelState values as Model properties
The ModelState Class in MVC is a class which contains the collection that has the key and values of the data submitted to server in the Post method.When MVC comes across the post it takes all the parameters in the post request and puts them in the instance of a ModelStateDictionary. Whenever the ModelState is active in server,the properties of the model are validated according to the validation attributes that are associated with them. And if any of the property is invalid it will be added to the error list. And the property ModelState.IsValid will be set to false. You can use this later on your code to check if everything is correct.
Refer this link for further information.
Related
I'm really confused by this... still.
I asked a similar question to this a while before, but i'll ask it even simpler now.
I see this in a lot of samples and tutorials. How could you put [Bind(Exclude="ID")] on an entire Model, and expect to do Edits on the model? If you get pack all the properties of a model on a POST but not the ID, then how do you know which ID to edit?
Even if i'm using ViewModels... i'm probably creating them without IDs. So in that case... also... how do I know which ID was updated on an Edit?
Yes, i understand that there is a "security" element to this. People can hijack the ID... so we need to keep people from updating the value during a POST. But... what is the correct way to handle edits then? What's common practice?
I feel like i'm missing something VERY trivial.
In MVC requests are processed by the model binder when the client makes a request. If you include models on your controllers then, as far as I'm aware, you actually have to specify the model you wish to bind to by prefixing your arguments with the model name (unless you only have one argument which is the model)
SomeModel_ID
Now, in some cases you might want to exclude certain properties from being bound to because they pose a security risk, which you seem to be happy with as a concept. We will exclude ID on the model, preventing any client request from posting this value in plain text.
Now why might we exclude an entire model? Well not all controller arguments are pre-processed by a model binder. RedirectToAction for example does not pass through the model binder, so it is conceivable in this instance for you to create a new model in a POST controller action, and redirect to a GET controller action, passing along a sanitised model. That model cannot be populated by the client, but we are free to populate it ourselves on the server side.
The only time I bind to a model is when I have a view model and an associated editor for that model. This makes it really easy to inject a common editor into a page and to encapsulate those properties. If you have to exclude certain properties from being bound to I would argue that you are doing it wrong.
Update
Following your comments I think I can see why you might be confused. The model bind excluder prevents the client from ever setting a model property. If you need this property to do your updating then you simply can't exclude it. What this does mean then is that the user could potentially post back any ID. In this case you should check that the user has permission to be modifying any objects or database records associated with this ID before serving the requested update. Validating the arguments is a manual process. You can use data annotations for validating inputs, but this isn't likely to help very much with access permissions. It's something you should be checking for manually at some stage.
You know the ID because it's passed to you through the page address. So:
http://yoursite.com/admin/users/edit/20
Will populate your ID parameter with 20. If it's used in a POST (ie, the information is filled in), just manually fill in the ID field and pass it to the database controller in whatever manner you have devised.
This is also immune to (trivial) hijacks because if they were to write some other ID besides 20, they wouldn't be updating the user with ID 20 now would they? :)
When to use ViewBag, ViewData, or TempData in view.
In the controller i want to send object to the view.I want to know that which will be best in this case.
I want the object in the view page.
Use TempData when you need data to be available for the next request, only.
TempData["myInfo"] = "my info";
Then in the next request, it will be there... but will be gone after that.
Use ViewBag for most of your extra-data needs to pass to your view, beyond the #model
ViewBag.MyInfo = "my info";
Then access it from your view.
Use ViewData to access/enter the exact same info as ViewBag, except as a collection instead of properties of a dynamic object.
ViewData["MyInfo"]
accesses exactly the same data as ViewBag.MyInfo
Note that I used strings, but these can store any object you wish.
Another thing to note: TempData and ViewData are both dictionaries that store object values, so you must cast those to their original type when you use them. ViewBag however uses dynamic, and you don't always need to cast that, since it is done at runtime. Some methods (like Extension methods) can not handle dynamic though, so you would need to cast in those cases.
IMHO for decent design practies -
ViewBag = never.
ViewData = never.
These are magic string-ish based fields and canot be caught during any compile time instances either.
Your VieWModel should contain everything it needs.
Thats it's purpose in life. Don't devoid it of its purpose. TempData for status messages only or object you don't want to cache but wan't available for the very next request only.
I have a queryparameter named "from" (a from date)
and also a input which binds to a property named From
In my ViewModel contructor i set the From property to a date...
This works if the query parameter name and the property name are different, but if they are same MVC3 with some magic takes whatever value there are in the query param and binds against that, it does not care what value are in the From property.. Why? this atuomagic is so wrong on so many levels! How do I disable it?
edit: It doesnt matter what value the Property gets, if a querystring exists with the same id as the input MVC automatic takes that value and assign it to the input element
You need to call
ModelState.Clear();
Before returning from your controller action.
The issue is that the ModelState has the value from the query string, and that takes precedence over the value in your model when binding occurs.
Whether this is a bug or a feature depends on your point of view... http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx
MVC works by convention, and binds values to the model by names. To understand what is happening, I suggest you read this blog article from Phil Haack: What’s the Difference Between a Value Provider and Model Binder?
It is bad practice to have two unrelated elements with identical names in the same request, as a name collision is very likely to cause unexpected problems. Best practice is to rename one of these elements so that you eliminate the name collision.
We have our POCO classes setup using Data Annotations.
For one of these classes, we invole more than one view for the user to populate all of their data. For example if it were a class with username and password as properties we would on the first page get the user to specify their username and on the second page specify their password.
Now, if i use the full POCO class (which requires that both username & password are supplied) then when we ask ModelState.IsValid were get false since the password hasn't yet been supplied, but we know that the password is going to be supplied on the next page!
Is there a generic way for us to validate those elements of the model for which values should have been provided rather than the whole Model? I know that i can remove the errors for individual items from the ModelState.
I know that we could separate out the model elements to have separate models for each page part of the entry that is being performed but this feels like we are changing the underlying class to fit more with the view.
Regards
Jamie
I believe the approach here by Steve deals with this
http://blog.stevensanderson.com/2010/02/19/partial-validation-in-aspnet-mvc-2/
in essence he filters out those keys for which there are no incoming values.
Try putting the validation on the ViewModel classes. Each view will have its own ViewModel class. One with the username, the other with the password. Don't use the model until you gathered all the data you need.
I have created a create view within my MVC 2.0 Application and by default it included a field for the integer ID Column.
This is definitely a field i do not need.
If i remove the field and use updatemodel when trying to create the object in code, will something break because it doesnt see my ID column data being passed in, even though it is auto increment?
Also, i noticed that in the NerdDinner example, updatemodel was used and after that the repository.save method was called.
I thought that updatemodel would save the object to the database..why then call the .save method afterwards? Or have i missed something?
Any help with this would be appreciated.
Cheers
As I understand it, the UpdateModel method will blow away all data in the object. This is because MVC is round-trip based. Anything that goes out should come back if you need to keep state. See this question for more details.
A better way to handle this scenario in my opinion is to have an input model class as an Action parameter which is passed to a service call to update the domain entity in the DB. (Or this mapping code could be right in the action method if you really want.)
Also please be aware of the security vulnerabilities that could be introduced by binding directly to your DB model.