ModelState.IsValid does not exclude the required property

I am trying to exclude the required property (Password), so modelstate does not check this property, but for some reason it still checks, even when I try to exclude it.

Controller:

[Authorize, AcceptVerbs(HttpVerbs.Post)] public ActionResult _Edit(int id, [Bind(Exclude = "Password")]FormCollection collection) { var user = Proxy.GetUser(id); TryUpdateModel(user, null, null, new[]{"Password"}); if(!ModelState.IsValid) return PartialView(user); Proxy.UpdateUser(user); } 

View:

  ... <tr> <td class="label"> <label class="row_description" for="Password"><%= S._("Password")%></label> </td> <td> <%= Html.Password("Password", null, new { @class = "row_input" })%> <%= Html.ValidationMessage("Password", "*")%> </td> </tr> 

User (using dataannotation):

 [Required] public string Password { get; set; } 

Im using VS2008, MVC2, firefox

Maybe I'm just tired and don't see him. Any help is appreciated.

+7
asp.net-mvc
source share
6 answers

I am currently facing a similar problem with MVC3.

Despite [Bind(Exclude = "Password")] in my Action, ModelState.IsValid still returns false.

I noticed that TryUpdateModel(user, null, null, new string[]{"Password"}); successfully updated the model; but still returns a lie. Then I found out (somewhere in stackoverflow, apologies for the lack of a link) that TryUpdateModel really returns ModelState.IsValid .

So the problem is not with TryUpdateModel , but with ModelState.IsValid .

NB: this also means you don't need to check this twice ... you can use this code:

 if (!TryUpdateModel(user, null, null, new string[]{"Password"})) return PartialView(user); 

The problem is as if ModelState is still checking properties that were excluded from your FormCollection .

I managed to overcome this by removing the field from ModelState before calling TryUpdateModel :

 ModelState.Remove("Password"); 

Note that TryUpdateModel still requires that the property list be excluded from the update in accordance with the code above.

+14
source share

I had success using the following method in ASP.NET MVC 2

 TryUpdateModel(user); ModelState.Remove("Password"); if (!ModelState.IsValid) return PartialView(user); 

To link the TryUpdate link to specific model properties, you can create an inclusion template, for example, the following:

 public interface IUserValidateBindable { string UserId { get; set; } } public class User : IUserValidateBindable { [Required] public string UserId { get; set; } [Required] public string Password { get; set; } } 

An update to the TryUpodateModel call is performed as follows:

 TryUpdateModel<IUserValidateBindable>(user); 
+3
source share

Maybe you should replace

 TryUpdateModel(user, null, null, new[]{"Password"}); 

from

 TryUpdateModel(user, null, null, new string[] {"Password"}); 

Because it can be confusing which overload for TryUpdateModel is used. Just saying ...

0
source share

I successfully used [Bind(Exclude = "Property")] and ModelState.Remove("Property") together, and it worked like a charm.

0
source share

You can use the extension method as follows:

 public static bool IsValidExclude(this ModelStateDictionary modelState, params string[] exclude) { foreach (var key in exclude) { if (modelState.ContainsKey(key)) modelState.Remove(key); } return modelState.All(m => m.Value.Errors.Count == 0); } 

Then just call:

 var result = ModelState.IsValidExclude("Password"); 
0
source share

It seems like I answer too late, but I also had the same problem.

Check out the ModelState.Keys collection. The keys can be in the form of modelObjectName.Password and are the same for the other properties of the model.

So, in this case ModelState.Remove("Password") will not work. You should try ModelState.Remove("modelObjectName.Password")

Hope this solves someone the problem :)

-2
source share

All Articles