MVC :: TryUpdateModel Versus ModelState.IsValid
Feb 9, 2011The latest MVCSaffolding package uses "if (ModelState.IsValid)" prior to saving changes. In the past I have seen TryUpdateModel... used.
Is there a best practice?
The latest MVCSaffolding package uses "if (ModelState.IsValid)" prior to saving changes. In the past I have seen TryUpdateModel... used.
Is there a best practice?
explain to me the difference between these two? I'm new to MVC and can't seem to find an explanation anywhere.
View 3 RepliesI am working in an ASP.NET MVC Application. I have a view model as follows:
[code]....
From UI Perspective user can enter date as mmddyyyy. And when user enters in such format 01012001, my ModelState.IsValid code piece in controller returns false. When I did a quick watch in ModelState, I see an error for the propery "SampleDate", saying "The Value 01012001 is not valid for SampleDate".
In my modelbinder, during the OnModelUpdated event I tried to format the value 01012001 to 01/01/2001 and assigned it back to SampleInterestViewModel.SampleDate thinking that ModelState.IsValid might return true without that error. But still ModelState.IsValid is false and I when I looked in to the ModelState dictionary, this particular property still has that errors in its collection.
Lastly I tried to format 01012001 and update the value 01/01/2001 directly to the Property SampleDate in the ModelState dictionary. But still ModelState.IsValid is false showing the same error for the SampleDate property. Can't figure out why ModelState.IsValid works and how and when it gets set to false.
If the User enter 01012001 in the UI, I still need to format it in the modelbinder to 01/01/2001 and make sure that ModelState.IsValid it true so that the rest of my controller code can work as expected. In the UI I am doing an AjaxSubmit to post the sampleDate value.
Is it necessary to do a ModelState.IsValid check at the top of every action? It seems that it is since the default model binder could make it invalid depending on the action parameters.
View 3 RepliesI try to create a asp.net mvc 2 application.
My DropDownList won't be validated!
I have a core model class called Animal with some attributes and the same for the class Genus. These classes are mapped to nHibernate.
[code]....
What is the difference between; Deploying an application Releasing an application Implementing an application
View 1 RepliesI've gone rounds with this ever since I started programming classic ASP 12 (or so) years ago and I've never found a great solution because the architecture of ASP and ASP.NET has always been a swamp of bad practices, magic shared singletons, etc. My biggest issue is with the HttpApplication object with its non-event events (Application_Start, Application_End, etc.).
If you want to do stuff once for the entire lifespan of an HTTP application, Application_Start is the obvious place to do it. Right? Not exactly. Firstly, this is not an event per se, it's a magic naming convention that, when followed, causes the method to be called once per AppDomain created by IIS.
Besides magic naming conventions being a horrible practice, I've started to think it might be a reason there exist no such thing as a Start event on the HttpApplication object. So I've experimented with events that do exist, such as Init. Well, this isn't really an event either, it's an overridable method, which is the next best thing.
It seems that the Init() method is called for every instantiation of an HttpApplication object, which happens a lot more than once per AppDomain. This means that I might as just put my startup logic inside the HttpApplication object's constructor.
Now my question is, why shouldn't I put my startup logic in the constructor? Why does even Init() exist and do I need to care about Application_Start? If I do, can anyone explain why there is no proper event or overridable method for this pseudo-event in the HttpApplication object?
And can anyone explain to me why in a typical ASP.NET application, 8 instances of my HttpApplication are created (which causes the constructor and Init to run just as many times, of course; this can be mitigated with locking and a shared static boolean called initialized) when my application only has a single AppDomain?
I have a view that displays a list of entities; I need to provide user a way to bulk-edit some properties of these entities. To do that I generate a form like the following:[Code]....
Next, I use javascript to submit user-entered values:[Code]....
Submitted data is processed by the following action:
[Code]....
Quantity and Price properties of the entities in the collection are updated as desired. However, all other properties are reset to null. AFAI, specifying the properties in "excludeProperties" list should
prevent them from being changed by TryUpdateModel, right? What am I missing here?
I have following problem: in the Controller I call TryUpdateModel to send the changes made in the form back to the database. Then I save the entity, but no changes to database are made.
Here is the code from Controller:
[Code]....
Then the changes made to database. (ChangingSet have then also pending changes).
I have a strongly typed Edit view that expects a viewmodel class. On its post action, I want it to use TryUpdateModel to update the database with the new info. When debugging, TryUpdateModel returns true, but when I look in the database, nothing happened.
This is the controller Action
[Code]....
why this doesn't persist the changes back to the database?
I have a form when I post back TryUpdateModel is True But it is not updating the database.
MVC 2
I am following though the examples in Professional ASP.Net MVC 2 and one of the examples doesn't work for me.
[HttpPost]
public ActionResult Edit (int id, FormCollection collection)
{
Dinner dinner = dinnerRepository.GetDinner(id);
if (TryUpdateModel(dinner))
{
dinnerRepository.Save();
return RedirectToAction("Details", new { id = dinner.DinnerID });
}
return View(new DinnerFormViewModel(dinner));
}
I understand that it's suppose to take the values from the FormCollection, and then update the dinner object with it, bit I don't see the collection get referenced anywhere.
I am trying to bind the dynamic object using TryUpdateModel(); but it works for first class member but it is not updating the properties of object which are referenced to model.
View 4 Repliesi have an entity called User with 2 properties called UserName and Role (which is a reference to another entity called Role). I'm trying to update the UserName and RoleID from a form which is posted back. Within my postback action i have the following code:
var user = new User();
TryUpdateModel(user, "User", new string[] { "UserName, Role.RoleID" });
TryUpdateModel(user, new string[] { "User.UserName, User.Role.RoleID" });
However none of these updates the Role.RoleID property. If i try the following:
TryUpdateModel(user, "User", new string[] { "UserName, Role" });
TryUpdateModel(user);
The RoleID is updated but the RoleName property is validated aswell. That's why i'm trying to be more specific on which properties to update but i can't get any of the first examples to work.
Since I upgraded from MVC 2 to MVC 3 RC, using TryUpdateModel causes a NullReferenceException. This problem only occurs when running my action method as part of a unit test. Running it on the actual server works as expected. Here's a stack trace of the exception:
System.NullReferenceException: Object reference not set to an instance of an object. at System.Web.Mvc.JsonValueProviderFactory.GetValueProvider(ControllerContext controllerContext) at System.Web.Mvc.ValueProviderFactoryCollection.<>c_DisplayClassc.b_7(ValueProviderFactory
factory) at System.Linq.Enumerable.WhereSelectEnumerableIterator[Code]....
2.MoveNext()
at
System.Collections.Generic.List[Code]....
1
collection) at
System.Linq.Enumerable.ToList[TSource](IEnumerable`1
source) at
System.Web.Mvc.ValueProviderFactoryCollection.GetValueProvider(ControllerContext
controllerContext) at
System.Web.Mvc.Controller.TryUpdateModel[TModel](TModel
model, String prefix)
... my own code from here on....
In case it matters, my controller has the following signature:
[Code]....
My guess is that this has to do with the new way DI works in MVC3, but I can't figure out what I'm doing wrong. Perhaps there is something in terms of DI setup that is required in MVC 3, but wasn't required in MVC 2?
when trying to update the db from the edit page, i would likt to take one field from the formcollection change things in it and update the model with the changed field.
what is the correct syntax to do that?
I have cause validation true on button. And I am checking the Page.IsValid in c# code. But its always returning false value?
View 2 RepliesI'm using ASP.NET MVC 2 RC 2 (verified, the DLL has been signed on Friday, 29. January 2010 7:14:16 pm).
I created a custom validation attribute, which is described here (blog post is in German, however the code is not).
The problem is: that all works fine in theory (and unit tests). But by executing it in "the real world", which means firing off a form post to the server, it doesn't work. The commited validationContext is always null.
Is that a known issue? I would call that a real bug because it makes it impossible to use that method. And by using the other one I don't have access on the given context.
I'm using CustomValidator with Page.IsValid=false but for some reason the FormView control still process the insertion.
View 10 RepliesI am using a wizard control in which I have a next button that has causes validation = true. I also have a checkbox that when changed, in the event handler, I set causes validation = false for the next button. When that button is clicked - I get the following:
Page.IsValid cannot be called before validation has taken place. It should be queried in the event handler for a control that has CausesValidation.
Here is the code:
protected void chk_CheckChanged(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
ImageButton ibtnStepNext = (ImageButton)(this.WizardSummaryTemplate.CustomNavigationTemplateContainer.FindControl("StepNextButton"));
ibtnStepNext.CausesValidation = (!chk.Checked);
}
What would be the recommended solution to disabling validation for the next button so I don't see this error?
I want to pop up a message box when page.isvalid = false. How to do that?
[code]....
Model is coming up as Invalid Scenario is I have a custom ViewModel and certain fields don't show up on the screen (like Id & some computed fields etc..) so when the data gets posted back the Model.IsValid() comes to false Q Do I have to pre init these fields when I do create
ActionResult CreateOrder(int customerID)
{
var order=new OrderViewModel();
//shall I init the fields which are not being keyed in by the user?
}
In our code, we have to give the users a list of printers to choose from. The user then chooses a printer and it is checked to verify it is valid before printing. On a windows 2003 server with IIS 6, this works fine. On a windows 2008 server with IIS 7, it fails each time impersonate is set to true.
PrinterSettings printerSetting = new PrinterSettings();
printerSetting.PrinterName = ddlPrinterName.SelectedItem.Text;
if (!printerSetting.IsValid)
{
lblMsg.Text = "Server Printer is not valid.";
}
else
{
lblMsg.Text = "Success";
}
Each time this code is run, the "Server Printer is not valid" displays, only if impersonate is set to true. If impersonate is set to false, the success message is displayed. The impersonation user has full rights to the printer. Is there a way to catch the actual reason the printer is not valid? Is there some other 2008 setting I should check? update I found that IsValid fails when the IIS7 application pools has "Enable 32-bit applications" is checked. This must be checked b/c we are using a 3rd party tool to print with, and it is a 32-bit application. It is not currently part of this test, so right now it is not causing this error.
I am a bit baffled... I had my validation working fine till I added a validation group to it. Can someone tell me what i might be missing ? I'm at a loss... As I have another page doing the same thing and it works fine. Page.isValid always comes back as true.( I am just clicking on the button to make all the validation fire off.... )
[Code]....
[Code]....
I have an CustomViewModel that is composed of three layers of objects.
The first one is to store and populate lists to be used in dropdowns.
The second one is to store additional propperties that I want.
And the third one is the model itself.
I create the view using View(new Layer(model))
And at the post i have ActionResult .... (Container container)
I made this architecture because i was having a lot of problems with model binder and enums...
So when i post to the form and the ModelBinder checks the validation attributes, the IsValid operation at the attribute X applied to the model class has its parameter value as null.
This behavior doesn't happen if I Just use the simple model to create and post the view.
What I have to do to get this work ?
I made a few changes to the AccountController to use it as sample here, here is the code:
[Code]....
Just change the register page to inherits from RegisterModelLayer.
When I post, the value parameter at the IsValid function at the PropertiesMustMatchAttribute class is null;
As a consequence i can't validate and get an null exception maybe.