Disable Required validation attribute under certai

2019-01-03 14:00发布

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.

15条回答
甜甜的少女心
2楼-- · 2019-01-03 14:19

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.

查看更多
时光不老,我们不散
3楼-- · 2019-01-03 14:19

AFAIK you can not remove attribute at runtime, but only change their values (ie: readonly true/false) look here for something similar . As another way of doing what you want without messing with attributes I will go with a ViewModel for your specific action so you can insert all the logic without breaking the logic needed by other controllers. If you try to obtain some sort of wizard (a multi steps form) you can instead serialize the already compiled fields and with TempData bring them along your steps. (for help in serialize deserialize you can use MVC futures)

查看更多
老娘就宠你
4楼-- · 2019-01-03 14:20

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

查看更多
Evening l夕情丶
5楼-- · 2019-01-03 14:21

this was someone else's answer in the comments...but it should be a real answer:

$("#SomeValue").removeAttr("data-val-required")

tested on MVC 6 with a field having the [Required] attribute

answer stolen from https://stackoverflow.com/users/73382/rob above

查看更多
贪生不怕死
6楼-- · 2019-01-03 14:24

Yes it is possible to disable Required Attribute. Create your own custom class attribute (sample code called ChangeableRequired) to extent from RequiredAtribute and add a Disabled Property and override the IsValid method to check if it is disbaled. Use reflection to set the disabled poperty, like so:

Custom Attribute:

namespace System.ComponentModel.DataAnnotations
{
    public class ChangeableRequired : RequiredAttribute
    {
       public bool Disabled { get; set; }

       public override bool IsValid(object value)
       {
          if (Disabled)
          {
            return true;
          }

          return base.IsValid(value);
       }
    }
}

Update you property to use your new custom Attribute:

 class Forex
 {
 ....
    [ChangeableRequired]
    public decimal? ExchangeRate {get;set;}
 ....
 }

where you need to disable the property use reflection to set it:

Forex forex = new Forex();
// Get Property Descriptor from instance with the Property name
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(forex.GetType())["ExchangeRate"];
//Search for Attribute
ChangeableRequired attrib =  (ChangeableRequired)descriptor.Attributes[typeof(ChangeableRequired)];

// Set Attribute to true to Disable
attrib.Disabled = true;

This feels nice and clean?

NB: The validation above will be disabled while your object instance is alive\active...

查看更多
The star\"
7楼-- · 2019-01-03 14:25

The cleanest way here I believe is going to disable your client side validation and on the server side you will need to:

  1. ModelState["SomeField"].Errors.Clear (in your controller or create an action filter to remove errors before the controller code is executed)
  2. Add ModelState.AddModelError from your controller code when you detect a violation of your detected issues.

Seems even a custom view model here wont solve the problem because the number of those 'pre answered' fields could vary. If they dont then a custom view model may indeed be the easiest way, but using the above technique you can get around your validations issues.

查看更多
登录 后发表回答