u936293
u936293

Reputation: 16264

Is it possible to update ModelState.IsValid manually?

I would like to use the built-in validation features as far as possible. I would also like to use the same model for CRUD methods.

However, as a drop down list cannot be done using the standard pattern, I have to validate it manually. In the post back method, I would like to just validate the drop down list and add this result to ModelState so that I don't have to validate all the other parameters which are done with Data Annotation. Is it possible to achieve this?

I may be mistaken about the drop down list, but from what I read, the Html object name for a drop down list cannot be the same as the property in the Model in order for the selected value to be set correctly. Is it still possible to use Data Annotation with this workaround?

Thanks.

Upvotes: 32

Views: 44336

Answers (5)

dchang
dchang

Reputation: 1141

Might be more recent methods, since this is an old post, but this might help future readers.

One can set a field to valid with this two methods:

ModelState.ClearValidationState("Password");
ModelState.MarkFieldValid("Password");

Need to use both because the second one without the first one it gives an error stating that the state is already marked.

To set a field to invalid, just use ModelState.AddModelError() method as already referred.

Upvotes: 1

Chtioui Malek
Chtioui Malek

Reputation: 11515

yes, you can achieve this (also you will use the same model for CRUD methods) :

Example MODEL

public class User 
{
    public virtual int Id{ get; set; }
    public virtual Role Role { get; set; }
}
public class Role 
{        
    [Required(ErrorMessage = "Id Required.")]
    public virtual int Id { get; set; }
    [Required(ErrorMessage = "Name Required.")]
    public virtual string Name { get; set; }
}

Example VIEW with validation on the dropdownlist

@Html.DropDownListFor(m => m.Role.Id, (SelectList)ViewBag.gRoles, "-- Select --")
@Html.ValidationMessageFor(m => m.Role.Id)

CONTROLLER: clearing the required (but not needed here) fields

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Creedit(User x)
{
    x.Role = db.RoseSet.Find(x.Role.Id);
    if (x.Role != null)
    {
        ModelState["Role.Name"].Errors.Clear();

    }

    if (ModelState.IsValid)
    {
      // proceed
    }
    else
    {
      // return validation error
    }
}

Upvotes: 4

Tim Coker
Tim Coker

Reputation: 6524

Another option is to inherit IValidatableObject in your model. Implement its Validate method and you can leave all other validation in place and write whatever code you want in this method. Note: you return an empty IEnumerable<ValidationResult> to indicate there were no errors.

public class Class1 : IValidatableObject
{
    public int val1 { get; set; }
    public int val2 { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        var errors = new List<ValidationResult>();
        if (val1 < 0)
        {
            errors.Add(new ValidationResult("val1 can't be negative", new List<string> { "val2" }));
        }
        if (val2 < 0)
        {
            errors.Add(new ValidationResult("val2 can't be negative", new List<string> { "val2" }));
        }
        return errors;
    }
}

EDIT: After re-reading the question I don't think this applicable to this case, but I'm leaving the answer here in case it helps someone else.

Upvotes: 18

Gabriele Petrioli
Gabriele Petrioli

Reputation: 196217

You can use the addModelError

ModelState.AddModelError(key,message)

when you use that, it will invalidate the ModelState so isValid will return false.


Update
after seeing the comment to @Pieter's answer

If you want to exclude an element from affecting the isValid() result, you can use the ModelState.Remove(field) method before calling isValid().

Upvotes: 80

Pieter Germishuys
Pieter Germishuys

Reputation: 4886

You cannot manually set the ModelState.IsValid property but you can add messages to the ModelState that will ensure that the IsValid is false.

ModelState.AddModelError();

Upvotes: 5

Related Questions