MmM
MmM

Reputation: 3591

Creating a custom ValidationAttribute class that returns multiple error messages

I have a model like this:

[IsValidInput]
public class Input
{
    //different properties
}

With a custom validation attribute like this:

[AttributeUsageAttribute(AttributeTargets.Class, AllowMultiple = true, Inherited = false)]
public class IsValidInput : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        try
        {
            ExternalValidator.Validate(value);
        }
        catch (CustomException ex)
        {
            foreach(var errorText in ex.GetDescriptions())
            {
                this.ErrorMessage = this.ErrorMessage + errorText;
            }
            return false;
        }
        return true;
    }
}

Now I have one ErrorMessage object that contains multiple errors. I want to somehow return multiple ErrorMessage objects, so that in my view I will have a list with multiple list-items, like this:

How can I return a list of ErrorMessages to archieve this?

Upvotes: 5

Views: 8091

Answers (3)

MmM
MmM

Reputation: 3591

I've found a workaround:

I'll append my error message with some html tags like this:

foreach(var errorText in ex.GetDescriptions())
{
    this.ErrorMessage = this.ErrorMessage + txt + @"</li><li>";
}
this.ErrorMessage = this.ErrorMessage.Remove(this.ErrorMessage.Length - 4);

And add @Html.Raw in my view:

@if (Html.ValidationSummary() != null) { @Html.Raw(HttpUtility.HtmlDecode(Html.ValidationSummary().ToString())); } 

This will give me the html list with validation results that I want.

Upvotes: 2

Pawel Maga
Pawel Maga

Reputation: 5807

Hi you can return simple ValidationResult class instead of boolean:

 public class ValidationResult
 {
    public bool IsValid { get; set; }
    public IList<string> Errors { get; set; }

    public ValidationResult()
    {
        Errors = new List<string>();
    }
 }

public class IsValidInput
{
    public ValidationResult IsValid(object value)
    {
        ValidationResult result = new ValidationResult();

        try
        {
            ExternalValidator.Validate(value);
            result.IsValid = true;
        }
        catch (CustomException ex)
        {
            foreach(var errorText in ex.GetDescriptions())
            {
                result.Errors.Add(this.ErrorMessage + errorText);
            }
        }
    }
    return result;
}

Upvotes: 3

Carl Prothman
Carl Prothman

Reputation: 1551

Check out this solution: http://www.codeproject.com/Articles/234096/Multiple-Custom-DataAnnotations-on-Same-Field-With

1) Use a static field which will keep track of how many attributes per field or property there are, and as per the count, appends letters a, b, c... in the ValidationType of each next rule produced for the field or property.

2) Provide a custom HTML Helper to render the editor for the field; the HTML Helper will then parse all "HTML-5 data-val" attributes on the field and will convert them to a requiredifmultiple rule (client side rule which doesn't change anything on the server side code) for the field.

3) Provide two adaptors and validation functions for the client side validation of this custom validation attribute, one if there is only one instance of the Attribute on the field (i.e., RequiredIf), another when there are multiple instances of the Attribute on the field (i.e., RequiredIfMultiple).

Upvotes: 0

Related Questions