Disable Required validation attribute under certain circumstances

198,999

Solution 1

This problem can be easily solved by using view models. View models are classes that are specifically tailored to the needs of a given view. So for example in your case you could have the following view models:

public UpdateViewView
{
    [Required]
    public string Id { get; set; }

    ... some other properties
}

public class InsertViewModel
{
    public string Id { get; set; }

    ... some other properties
}

which will be used in their corresponding controller actions:

[HttpPost]
public ActionResult Update(UpdateViewView model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertViewModel model)
{
    ...
}

Solution 2

If you just want to disable validation for a single field in client side then you can override the validation attributes as follows:

@Html.TextBoxFor(model => model.SomeValue, 
                new Dictionary<string, object> { { "data-val", false }})

Solution 3

I know this question has been answered a long time ago and the accepted answer will actually do the work. But there's one thing that bothers me: having to copy 2 models only to disable a validation.

Here's my suggestion:

public class InsertModel
{
    [Display(...)]
    public virtual string ID { get; set; }

    ...Other properties
}

public class UpdateModel : InsertModel
{
    [Required]
    public override string ID
    {
        get { return base.ID; }
        set { base.ID = value; }
    }
}

This way, you don't have to bother with client/server side validations, the framework will behave the way it's supposed to. Also, if you define a [Display] attribute on the base class, you don't have to redefine it in your UpdateModel.

And you can still use these classes the same way:

[HttpPost]
public ActionResult Update(UpdateModel model)
{
    ...
}

[HttpPost]
public ActionResult Insert(InsertModel model)
{
    ...
}

Solution 4

You can remove all validation off a property with the following in your controller action.

ModelState.Remove<ViewModel>(x => x.SomeProperty);

@Ian's comment regarding MVC5

The following is still possible

ModelState.Remove("PropertyNameInModel");

Bit annoying that you lose the static typing with the updated API. You could achieve something similar to the old way by creating an instance of HTML helper and using NameExtensions Methods.

Solution 5

Client side For disabling validation for a form, multiple options based on my research is given below. One of them would would hopefully work for you.

Option 1

I prefer this, and this works perfectly for me.

(function ($) {
    $.fn.turnOffValidation = function (form) {
        var settings = form.validate().settings;

        for (var ruleIndex in settings.rules) {
            delete settings.rules[ruleIndex];
        }
    };
})(jQuery); 

and invoking it like

$('#btn').click(function () {
    $(this).turnOffValidation(jQuery('#myForm'));
});

Option 2

$('your selector here').data('val', false);
$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

Option 3

var settings = $.data($('#myForm').get(0), 'validator').settings;
settings.ignore = ".input";

Option 4

 $("form").get(0).submit();
 jQuery('#createForm').unbind('submit').submit();

Option 5

$('input selector').each(function () {
    $(this).rules('remove');
});

Server Side

Create an attribute and mark your action method with that attribute. Customize this to adapt to your specific needs.

[AttributeUsage(AttributeTargets.All)]
public class IgnoreValidationAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        var modelState = filterContext.Controller.ViewData.ModelState;

        foreach (var modelValue in modelState.Values)
        {
            modelValue.Errors.Clear();
        }
    }
}

A better approach has been described here Enable/Disable mvc server side validation dynamically

Share:
198,999
Alex Hope O'Connor
Author by

Alex Hope O'Connor

Software Engineer working for DSITIA in Brisbane Australia.

Updated on July 08, 2022

Comments

  • Alex Hope O'Connor
    Alex Hope O'Connor almost 2 years

    I was wondering if it is possible to disable the Required validation attribute in certain controller actions. I am wondering this because on one of my edit forms I do not require the user to enter values for fields that they have already specified previously. However I then implement logic that when they enter a value it uses some special logic to update the model, such as hashing a value etc.

    Any sugestions on how to get around this problem?

    EDIT:
    And yes client validation is a problem here to, as it will not allow them to submit the form without entering a value.

  • Muhammad Adeel Zahid
    Muhammad Adeel Zahid about 13 years
    can we hook this on client side?
  • mindplay.dk
    mindplay.dk about 12 years
    client-side validation generally is done for individual fields only, performing interactive, field-by-field validation feedback, as a convenience to the user. Since the object-validation step generally involves dependent validation (multiple fields and/or conditions that are external to the object itself) this can't necessarily be performed on the client-side, even if you could compile the code to JavaScript. If complex/dependent validation on the client-side does add value in your case, you will need to use the onsubmit-callback and duplicate the validation logic on the client-side.
  • Rob Koch
    Rob Koch about 12 years
    What worked for me via jQuery: $("#SomeValue").removeAttr("data-val-required");
  • Rob Koch
    Rob Koch about 12 years
    Not always true if you have a boolean/bit that is not nullable. But really doesn't make a difference since its going to end up true or false. I had css to highlight required fields and it falsely highlighted the CheckBoxFor item. My solution: $("#IsValueTrue").removeAttr("data-val-required");
  • Yannick Smits
    Yannick Smits about 12 years
    I like this approach but I needed to re-parse the form validation attributes using: $('form').removeData('unobtrusiveValidation'); $('form').removeData('validator'); $.validator.unobtrusive.parse('selector for your form');
  • eth0
    eth0 about 12 years
    @Html.TexBoxFor(model => model.SomeValue, new { data_val = false }) - easier to read IMO.
  • Koby Hastings
    Koby Hastings almost 12 years
    In update we generally have (FormCollection collection). could you please explain how you are using model as parameter
  • Darin Dimitrov
    Darin Dimitrov almost 12 years
    No, we don't usually have Update(FormCollection collection), at least I never do. I always define and use a specific view model: Update(UpdateViewView model).
  • Felipe FMMobile
    Felipe FMMobile over 11 years
    I liked most of this approach to leave me give a fine control of each field, but you could add to cancel ModelState.IsValid when send data to save by POST. Maybe cause some risk ?
  • e11s
    e11s over 11 years
    Overloading methods with the same HTTP action are not allowed, so to me it seems like this would not work. Am I missing something?
  • Darin Dimitrov
    Darin Dimitrov over 11 years
    @edgi, no, you are not missing anything. It's a mistake in my post. The second action method should obviously be called Insert. Thanks for pointing this out.
  • Leniel Maccaferri
    Leniel Maccaferri almost 11 years
    If you want to disable it through jQuery: $(".search select").attr('data-val', false);
  • Yorro
    Yorro over 10 years
    I like this approach better, especially if you have a long list of validation attributes. In your example, you can add more attributes in the base class to have the benefit more apparent. The only disadvantage I can see is that there is no way for inheriting properties to override the attributes. Example, if you have a [Required] property on the base class, the inheriting property is forced to be [Required] also, unless you have a custom [Optional] attribute.
  • vincent de g
    vincent de g over 9 years
    I thought of something like this too, although I have a viewModel that has an object 'Project' that has multiple attributes and i only want one of these attributes validated under certain circumstances. I dont think i can just override a attribute of an object right? any advice?
  • PhilDulac
    PhilDulac over 9 years
    You can't override the attribute. The base class should only contain common attributes for all sub classes. Then, your sub classes should define the attributes they need.
  • Migro96
    Migro96 almost 9 years
    IT removes all the validation,is it possible to remove only required field validation without javascript
  • T-moty
    T-moty almost 9 years
    Most elegant, reusable, clear solution. Replications are bad. Polymorphism is the way. +1
  • T-moty
    T-moty almost 9 years
    What about server side validation?
  • Mike_Matthews_II
    Mike_Matthews_II almost 9 years
    ModelState.Remove, right? At any rate, for me, the issue was that I had a second entity being included in my model...the primary I wanted validation on, but the secondary didn't need validation on that page...so, under this scenario, only the JQuery was necessary.
  • T-moty
    T-moty almost 9 years
    I think that the link is broken, so please edit. This is a partial answer
  • Shimmy Weitzhandler
    Shimmy Weitzhandler over 8 years
    I'm using ViewModels, but my VM inherits a base class that has a Title property attributed as Required, is there a way to disable that in the subclass?
  • bradlis7
    bradlis7 over 8 years
    @NayanaSetty try overriding the individual validation attributes: @Html.TexBoxFor(model => model.SomeValue, new { "data-val-required" = false }).
  • Ernest Gunning
    Ernest Gunning about 8 years
    After a few debates on this I would like to mention that I don't recommend disabling validation but rather review the rule. If you disable it, you creating a dependency to re-enable the rule and I would suggest review the rule.
  • Alexey Strakh
    Alexey Strakh almost 8 years
    in my case a base class has a required attribute and I want to make it non required in my parent class. Is it possible without having two copies of model?
  • Ian Kemp
    Ian Kemp over 7 years
    Except... there isn't a method on ModelState that matches that signature. Not in MVC 5, at least.
  • Sachin Pakale
    Sachin Pakale over 7 years
    $('input selector').each(function () { $(this).rules('remove');}); helped me
  • Luis Deras
    Luis Deras over 7 years
    This is just what I needed. I had one view and differente actions occur in this view, so I couldn't make it with differente ViewModels. This works like a charm
  • eaglei22
    eaglei22 about 6 years
    It's weird that you say this works in MVC6 (I don't have option to test on MVC6 currently) but does not work for me on MVC4 which I am currently using.
  • m.t.bennett
    m.t.bennett almost 6 years
    The question is for MVC/C# - not JS, the answer would not work server side
  • Richard
    Richard over 5 years
    The question wasn't how to remove all validation. It was how to remove required field validation. You might want to do this while leaving other validation rules in place.
  • Richard
    Richard over 5 years
    The question was specifically about removing required field validation, not about removing all validation. Your answer is about removing all validation.
  • Jeremy Lakeman
    Jeremy Lakeman over 5 years
    Changing a static value to completely disable all validation of that field executed within that same process sounds like a terrible idea.
  • Irf
    Irf over 4 years
    HI @DarinDimitrov, I Jus wanted to know, in case of complex models (as in MVC 5 ) with inheritance and dropdownList initializations before making a Get request.. what would be the best approach, for insert, update validation actions.. ..Separate Views?? or .. Thnx (Irfan)
  • Ali
    Ali almost 4 years
    Which model would you now use to create the database for EF? would you create another model?
  • PhilDulac
    PhilDulac almost 4 years
    @Ali Depends. The object structure exposed by your Web API doesn't necessarily suits your needs at the database level. If it does, you'd probably use the UpdateModel for the IDproperty. Otherwise, I'd create another object to properly fit what you need in the database and convert the UpdateModel into this new object (we use AutoMapper for that).
  • c-sharp-and-swiftui-devni
    c-sharp-and-swiftui-devni over 3 years
    This is indeed the best solution and what worked for me even in .net core thank you @jps ModelState.Remove("PropertyNameInModel");