FormNoValidate when using a custom ValidationAttribute

38 Views Asked by At

UPDATE

I have gotten around my issue by limiting the ModelState.IsValid check to not test when the button pressed was the delete. So maybe this IS the real fix, but if there were something I could test in the validation context to determine if I should or should not run the validation logic, that would be a slicker solution.


I have created a custom validation attribute and it works great (well except for this issue). I have multiple submit buttons on my form. One of those buttons has the formnovalidate attribute set.

However my custom validation is still being fired off and preventing the UI from processing. I'm guessing that in my custom validation class, there is something I may need to check to see if the button pressed that triggered the validation had that attribute set?

For simplicity - this is my model class:

[CustomValidation(ErrorMessage = "Please Select a choice")]
public List<SelectListItem> Foo { get; set; }

View

<button type="submit" class="btn btn-danger" formnovalidate="formnovalidate" name="command" value="Delete" title="Delete">
Delete
</button>

Custom validation

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public class CustomValidation : ValidationAttribute
{
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        // Dummy Holder for testing.. not the real logic
        if (value != null)
        {
            return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(this.ErrorMessage);
        }
    }
}
1

There are 1 best solutions below

0
Henil Patel On

-> First you can check FormNoValidate attribute is available or not in the request and attributes of the submit button that triggered validation.

-> In this modification code, the FormNoValidate attribute is not present that time we skip the validation logic.

-> Code :-

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Web;

public class CustomValidation : ValidationAttribute
{
  protected override ValidationResult IsValid(object value, 
  ValidationContext validationContext)
  {
       // Check if the request contains the formnovalidate attribute
       var httpContext = 
       validationContext.GetService(typeof(IHttpContextAccessor)) as 
       HttpContextAccessor;
       var formNoValidate = 
       httpContext?.HttpContext?.Request?.Form["formnovalidate"];

       // If formnovalidate is present, skip validation
       if (!string.IsNullOrEmpty(formNoValidate))
       {
          return ValidationResult.Success;
       }

        // Dummy Holder for testing.. not the real logic
        if (value != null)
        {
           return ValidationResult.Success;
        }
        else
        {
            return new ValidationResult(this.ErrorMessage);
        }
      }
    }