简体   繁体   中英

How to return the property that contains an error in a single method using INotifyDataErrorInfo?

Problem

I am able to implement a validation for each property with it's own separate method. The problem I have is, this is too much code having too many methods for each property - I am aiming to have all the methods into 1 single method.

I now encountered an issue, on how to identify which property contains an error within my single method.

Service

Here I built the service to check the Username and Password from the User property.

public interface ILoginValidationService
{
    bool ValidateUser(UserModel user, out ICollection<string> errors);
}

public class LoginValidationService : ILoginValidationService
{


    public bool ValidateUser(UserModel user, out ICollection<string> errors)
    {
        errors = new List<string>();
        if (string.IsNullOrWhiteSpace(user.FirstName))
        {
            errors.Add("First Name cannot be empty");
        }
        if (string.IsNullOrWhiteSpace(user.LastName))
        {
            errors.Add("Last Name cannot be empty");
        }

        return errors.Count == 0;
    }
}

Actual validation

Within here, I create 2 methods Validation and ValidateUser which takes a single parameter of the UserModel .

The Validation method, creates a new UserModel object, takes the FirstName and LastName from the public properties that the TextBox is binded to. Then it calls the ValidateUser(user) passing the user object.

In ValidateUser method, is where I encountered the problem.

This method currently takes the property of FirstName var prop = nameof(FirstName); just as an example for now.

Next, you'll see the bool isValid property, this validates the user.

It does it's validations and returns the errors to FirstName mentioned in var prop = nameof(FirstName); and here is the output: SEE IMAGE BELOW CODE

private ILoginValidationService ValidationService { get; set; }
private bool Validation()
{
    UserModel user = new UserModel
    {
        FirstName = FirstName,
        LastName = LastName
    };
    ValidateUser(user);
    return _validationErrors.Count == 0 ? false : true;
}
private void ValidateUser(UserModel user)
{
    var prop = nameof(FirstName);
    ICollection<string> validationErrors = null;
    bool isValid = ValidationService.ValidateUser(user, out validationErrors);

    if (!isValid)
    {
        _validationErrors[prop] = validationErrors;
        RaiseErrorsChanged(prop);
    }
    else if (_validationErrors.ContainsKey(prop))
    {
        _validationErrors.Remove(prop);
        RaiseErrorsChanged(prop);
    }
}

#region INotifyDataErrorInfo members

private readonly Dictionary<string, ICollection<string>> _validationErrors = new Dictionary<string, ICollection<string>>();

public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
private void RaiseErrorsChanged(string propertyName)
{
    if (ErrorsChanged != null)
        ErrorsChanged(this, new DataErrorsChangedEventArgs(propertyName));
}

public IEnumerable GetErrors(string propertyName)
{
    if (string.IsNullOrEmpty(propertyName)
        || !_validationErrors.ContainsKey(propertyName))
        return null;

    return _validationErrors[propertyName];
}

public bool HasErrors
{
    get { return _validationErrors.Count > 0; }
}
#endregion

Output

在此处输入图像描述

What it does, it displays the erorr below the FirstName .

Question

Where I currently have var prop = nameof(FirstName); how can I determine from bool isValid = ValidationService.ValidateUser(user, out validationErrors); which property has the error? And display the error relevant to it's Property?

Instead of working with an ICollection and string you could think about creating your own class to report on errors.
Something simple like:

class ErrorInformation
{
    public string PropertyName {get;}
    public string Message {get;}
}

In ValidateUser instead of adding string to your collection you could add instances of ErroInformation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM