Проверка пользовательских атрибутов C # в консоли - PullRequest
0 голосов
/ 13 октября 2018

Мой вопрос касается проверки с использованием пользовательских атрибутов в C #.

Я не совсем понимаю, как работает проверка.Я объявил атрибут с правилом проверки в нем, но когда следует выдать ошибку, это не так.

Атрибут:

[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
    public bool IsValid(object value)
    {
        if (value is string && (string)value != "")
        {
            return false;
        }
        return true;
    }

}

Внутри атрибута я проверяю, имеет ли свойство типстрока, и если ее значение является пустой строкой, потому что это то, что я должен проверить.

Задача состоит в том, чтобы проверить, является ли свойство string и является ли оно пустой строкой, тогда оно недопустимо, в противном случае оноis.

Мой Person класс:

class Person
{
    [NotNull]
    public string Name { get; set; }
}

Здесь я применяю пользовательский атрибут.

Основной метод:

class Program
{
    static void Main(string[] args)
    {
        Person p1 = new Person();
        p1.Name = "";

        Console.WriteLine("Validation done");
        Console.ReadKey();
    }
}

Thisгде я создаю экземпляр класса Person и присваиваю пустую строку свойству Name.Я предполагаю, что именно здесь следует выдать ошибку.

Так что мой вопрос: почему не применяется проверка?Если бы я как-то вызвал метод IsValid из атрибута сам по себе?

Я хотел бы получить некоторые пояснения по этому поводу, спасибо заранее!

Ответы [ 2 ]

0 голосов
/ 13 октября 2018
 public class BankAccount  
   {  
       public enum AccountType  
       {  
           Saving,  
           Current  
       }  
       [Required(ErrorMessage="First Name Required")]  
       [MaxLength(15,ErrorMessage="First Name should not more than 1`5 character")]  
       [MinLength(3,ErrorMessage="First Name should be more than 3 character")]  
       public string AccountHolderFirstName { get; set; }  
       [Required(ErrorMessage="Last Name Required")]  
       [MaxLength(15,ErrorMessage="Last Name should not more than 1`5 character")]  
       [MinLength(3,ErrorMessage="Last Name should be more than 3 character")]  
       public string AccountHolderLastName { get; set; }  
       [Required]  
[RegularExpression("^[0-9]+$", ErrorMessage = "Only Number allowed in AccountNumber")]  
       public string AccountNumber { get; set; }  

       public AccountType AcType { get; set; }  

       [AccountBalaceCheckAttribute]  
       public double AccountBalance { get; set; }  
   }  

Как проверить

public class GenericValidator   
{  
    public static bool TryValidate(object obj, out ICollection<ValidationResult> results)  
    {  
        var context = new ValidationContext(obj, serviceProvider: null, items: null);  
        results = new List<ValidationResult>();  
        return Validator.TryValidateObject(  
            obj, context, results,  
            validateAllProperties: true  
        );  
    }  
}

Пример

static void Main(string[] args)  
{  
    var bankAccount = new BankAccount();  
    ICollection<ValidationResult> lstvalidationResult;  

    bool valid = GenericValidator.TryValidate(bankAccount, out lstvalidationResult);  
    if (!valid)  
    {  
        foreach (ValidationResult res in lstvalidationResult)  
        {  
            Console.WriteLine(res.MemberNames +":"+ res.ErrorMessage);  
        }  

    }  
    Console.ReadLine();  
}  
0 голосов
/ 13 октября 2018

Атрибут сам по себе является просто «декоратором» свойства.Если ничто не вызывает его, он не будет автоматически выполняться или использоваться.

В вашем случае, однако, я не вижу смысла использовать атрибут, когда вы можете использовать само свойство:

private string _name = "";

public string Name
{
   get
   {
      return _name;
   }
   set
   {
      if ( string.IsNullOrEmpty(value) )
      {
          //throw or fallback
      }
      else
      {
          _name = value;
      }
   }
}

Проверка основных значений - это именно то, для чего отлично подходят установщики свойств задания.Если кто-то использует недопустимое значение, вы можете вызвать исключение или установить запасное значение, например.

Если вы все еще предпочитаете использовать атрибуты, вам все равно нужен код, который выполняет саму проверку.И все же любой может присвоить свойству любое допустимое значение, если только проверка не выполнена.

Например, ASP.NET MVC использует проверку атрибутов во время привязки модели - он проверяет атрибуты проверки напривязывает класс модели и проверяет его до начала выполнения метода действия.

Пример проверки атрибута

Вот простой пример того, как заставить ваш код работать с отражением.

Сначала приведем немного обновленную версию атрибута проверки:

[AttributeUsage(AttributeTargets.Property)]
public class NotNullAttribute : Attribute
{
    public bool IsValid(object value)
    {
        if (!string.IsNullOrEmpty(value as string))
        {
            return false;
        }
        return true;
    }
}

Ваш код на самом деле допускает только значение null или "", которое, я полагаю, противоположно тому, что вы хотели.Эта версия действительна только в том случае, если строка не null и не пуста.

Теперь создайте метод Validate в своем классе Program:

private static bool Validate(object model)
{
    foreach (var propertyInfo in model.GetType().GetProperties())
    {                
        foreach (var attribute in propertyInfo.GetCustomAttributes(true))
        {
            var notNullAttribute = attribute as NotNullAttribute;
            if (notNullAttribute != null)
            {
                if (!notNullAttribute.IsValid(propertyInfo.GetValue(model)))
                {
                    return false;
                }
            }
        }
    }
    return true;
}

Это в основном собирает всесвойства типа переданного параметра, проверяет все атрибуты свойств для NotNullAttribute и затем выполняет метод атрибута IsValid относительно текущего значения из model.

Наконец, вот как выможно вызвать его с Main:

static void Main(string[] args)
{
    Person p1 = new Person();
    p1.Name = "d";

    if (Validate(p1))
    {
        Console.WriteLine("Valid");
    }
    else
    {
        Console.WriteLine("Invalid");
    }

    Console.WriteLine("Validation done");
    Console.ReadKey();
}

Теперь, если вы планируете добавить больше атрибутов проверки, я бы сначала создал интерфейс:

public interface IValidationAttribute
{
    bool IsValid(object value);
}

Затем извлеките всю вашу проверкуатрибуты из IValidationAttribute и Validate метода используют IValidationAttribute вместо NotNullAttribute.Таким образом, код становится более ориентированным на будущее, так как вы можете просто программировать для интерфейса и добавлять новые атрибуты проверки в любое время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...