larole
larole

Reputation: 172

ModelState.IsValid does not exclude required property

Im trying to exclude a required property(Password) so the modelstate dont validate that property, but for some reason it still validate 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 im just tired and can't see it. Any help is appreciated

Upvotes: 9

Views: 19562

Answers (7)

Shojaeddin
Shojaeddin

Reputation: 2073

in my case I face error on modelstate.isValid with Remove that it does not work for me in webapi asp.net mvc then I track the error

enter image description here

then I add model ModelState.Remove("model.Description"); that I defined model as parameter then I used name of parameter and then modelstate works for me like below:

enter image description here

Upvotes: 0

Murphybro2
Murphybro2

Reputation: 2689

You could use an extension method like so:

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");

Upvotes: 2

Avtar Singh
Avtar Singh

Reputation: 11

Seems like I'm replying too late, but I also faced the same problem.

Check your ModelState.Keys collection. Keys might be in the form of modelObjectName.Password and same for rest of model properties.

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

Hope this resolve someone's issue :)

Upvotes: -1

Irina Scurtu
Irina Scurtu

Reputation: 1

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

Upvotes: 0

Roland Schaer
Roland Schaer

Reputation: 1668

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

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

To keep the TryUpdate from binding to certain model properties you can create an inclusion template such as the one below:

public interface IUserValidateBindable
{
    string UserId { get; set; }
}

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

The update the TryUpodateModel call as follows:

TryUpdateModel<IUserValidateBindable>(user);

Upvotes: 3

Mark van Proctor
Mark van Proctor

Reputation: 743

I am currently experiencing a similar issue with MVC3.

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

I noticed that TryUpdateModel(user, null, null, new string[]{"Password"}); was successfully updating the model; however still returning false. I then found out (somewhere on stackoverflow, apologies for not having the link) that TryUpdateModel actually returns ModelState.IsValid.

Thus, the issue is not with TryUpdateModel, but with ModelState.IsValid.

NB: this also means that you do not need to verify this twice... you can use this code:

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

The issue thus appears as if ModelState is still validating properties that have been excluded from your FormCollection.

I was able to overcome this by removing the field from ModelState prior to calling TryUpdateModel:

ModelState.Remove("Password");

Note that TryUpdateModel still requires the list of properties to exclude from the update as per the above code.

Upvotes: 17

Francisco
Francisco

Reputation: 4101

Maybe you should replace

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

with

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

Because it might be confusing which overload for TryUpdateModel is using. Just saying...

Upvotes: 0

Related Questions