5

Is there any way to remove model validation for some properties in a Model in ASP.Net MVC6.

I came across this post Is there a strongly-named way to remove ModelState errors in ASP.NET MVC

which suggests using, ModelBindingHelper.ClearValidationStateForModel(Type, ModelStateDictionary, IModelMetadataProvider, string).

But I am unable to find any further help on this.

Can anyone please suggest a working example of removing a model property using ClearValidationStateForModel?

Community
  • 1
  • 1
Naveed Ahmed
  • 10,048
  • 12
  • 46
  • 85
  • What are you trying to do ? You want to remove a model validation error for few properties ? – Shyju Apr 01 '16 at 16:42
  • Possible duplicate of [Is there a strongly-named way to remove ModelState errors in ASP.NET MVC](https://stackoverflow.com/questions/14008561/is-there-a-strongly-named-way-to-remove-modelstate-errors-in-asp-net-mvc) – KyleMit May 30 '18 at 12:32

4 Answers4

6

This should remove the validation errors for the Title property of your CreatePost view model.

[HttpPost]
public ActionResult Create(CreatePost model)  
{
    if (ModelState.IsValid)
    {
      //to do : Save and return something
    }   
    ModelBindingHelper.ClearValidationStateForModel(model.GetType(),
                                              ModelState,MetadataProvider,"Title");        
    return View(model);
}

Also, ModelState.ClearValidationState will also work.

ModelState.ClearValidationState("Title");

EDIT : As per the comment, OP wants to exclude a certain property to be validated based on another property value. This should work fine.

[HttpPost]
public ActionResult Create(CreatePost model)   //CreatePost model
{
    if (model.Type == 1)
    {
        ModelBindingHelper.ClearValidationStateForModel(model.GetType(), 
                                                    ModelState, MetadataProvider, "Title");
    }
    if (ModelState.IsValid)
    {
        // to do : Do useful stuff and return something
    }
    return View(model);
}
Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Both of these doesn't seem to work in ASP.Net MVC 6. Below is how I am using it: [HttpPost] public ActionResult Create(CreatePost model) { //I want to skip the validation for Title, so I added this line before checking ModelState.IsValid ModelBindingHelper.ClearValidationStateForModel(model.GetType(), ModelState,MetadataProvider,"Title"); if (ModelState.IsValid) { //to do : Save and return something } return View(model); } – Naveed Ahmed Apr 01 '16 at 17:51
  • What do you mean it does not work on MVC6 ? I just verified this in an MVC 6 project and it works fine (both dnx 451 and dnxcore50). Specifically what is not working for you ? – Shyju Apr 01 '16 at 18:11
  • 2
    I have different properties in a model one of them is Type and Other is Duration, I want to skip validation of Duration if the selected type is 1 whereas I want to run the validation for all other types. In MVC5 ModelState.Remove("Duration"); before checking ModelState.IsValid was working, this doesnt seem to work in MVC 6. I also tried your suggested solution i.e. ModelState.ClearValidationState("Duration"); before checking ModelState.IsValid, but it does work the ModelState.IsValid is returned as fails. I have verified all other properties of the model have valid data. – Naveed Ahmed Apr 01 '16 at 18:18
  • It should work ! I just verified it. See my updated answer. The code i posted works fine for me in MVC 6. Project. Put a breakpoint and see whether it is going inside your if condition. – Shyju Apr 01 '16 at 18:30
  • @Shyju I still use MVC 5 and I am trying to find the similar library for MVC 5. Where can I find out an open source for MVC 5? The link github.com/aspnet/Mvc/blob/… is just for MVC.Core. – Thomas.Benz Nov 09 '17 at 22:49
2

For new comers use

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

If its nested object then use objectname.propertyname.

this works on ASP.Net Core 6.0

Mohamad Elnaqeeb
  • 541
  • 4
  • 13
1

ModelBindingHelper is new to ASP.NET Core 2.0 / MVC6+

If you need to use against previous versions of .NET / ASP.NET, you can do the following per Simon_Weaver's answer on Is there a strongly-named way to remove ModelState errors:

Here's my solution - a RemoveFor() extension method on ModelState, modelled after MVC HTML helpers:

public static void RemoveFor<TModel>(this ModelStateDictionary modelState, 
                                     Expression<Func<TModel, object>> expression)
{
    string expressionText = ExpressionHelper.GetExpressionText(expression);

    foreach (var ms in modelState.ToArray())
    {
        if (ms.Key.StartsWith(expressionText + "."))
        {
            modelState.Remove(ms);
        }
    }
}

And here's how it's used:

if (model.CheckoutModel.ShipToBillingAddress == true) 
{
    // COPY BILLING ADDRESS --> SHIPPING ADDRESS
    ShoppingCart.ShippingAddress = ShoppingCart.BillingAddress;

    // REMOVE MODELSTATE ERRORS FOR SHIPPING ADDRESS
    ModelState.RemoveFor<SinglePageStoreModel>(x => x.CheckoutModel.ShippingAddress);
}

if (ModelState.IsValid) 
{
     // should get here now provided billing address is valid
}
KyleMit
  • 30,350
  • 66
  • 462
  • 664
  • I do this, and I verified that `this.ModelState.Values.All( ms => ms.Errors.Count == 0 )` however `this.ModelState.IsValid == false`. Why? – Dai Mar 27 '19 at 04:21
  • 1
    @Dai you need to call `MarkFieldValid()` after `ClearValidationState()`. Otherwise the ValidationState is `Unvalidated` which results in `ModelState.IsValid = false` – binco Apr 13 '19 at 10:38
1

I needed for validation to have an exception for a single field in the VM

In the controller, I am doing:

if ("true" == Condition)
{
    ModelState.Remove("KeyName");
}

If "KeyName" was the only error in the ModelState, it will now be true

if (ModelState.IsValid)
{   
    // ModelState.IsValid is true now
}
Spencer Sullivan
  • 527
  • 6
  • 13