Сделайте свойство / класс MVC обязательным условием - PullRequest
1 голос
/ 01 сентября 2011

У меня есть класс Address, который используется для свойств MailingAddress и BillingAddress в моей модели. Я хочу, чтобы был необходим MailingAddress, но не BillingAddress, но я не вижу способа сделать это с помощью DataAnnotations.

Если бы мне удалось установить атрибут [Required] в свойстве MailingAddress и каким-то образом определить логику того, как класс Address должен обрабатывать требуемую логику, я чувствую, что это было бы простым решением.

Есть идеи?

Ответы [ 3 ]

1 голос
/ 01 сентября 2011

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

Получите все свойства рассматриваемого типа, а затем посмотрите, имеет ли он атрибут RequiredAttribute или нет.

class ParentClass
{
      [Required]
      public Address MailingAddress { get; set; }

      public Address BillingAddress { get; set; }
}

(...)

Type t = typeof(ParentClass);

foreach (PropertyInfo p in t.GetProperties())
{
    Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
    if (a != null)
    {
          // The property is required, apply your logic
    }
    else
    {
          // The property is not required, apply your logic
    }
}

Редактировать: исправлена ​​опечатка в коде

Редактировать 2: Пример расширенного кода

0 голосов
/ 01 сентября 2011

Множество вариантов доступно по ранее заданному вопросу:

Условная проверка ASP.NET MVC

Вам нужна эта проверка на стороне клиента или нет?

IValidateableObject будет использоваться в сочетании с любым из ваших существующих атрибутов и может предусматривать дополнительную пользовательскую проверку.

0 голосов
/ 01 сентября 2011

Это просто странная причуда, которая пришла мне в голову:

Простое решение может заключаться в том, чтобы создать подкласс Address для OptionalAddress.

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

[AttributeUsage (Inherited = False)] также приходит на ум при необходимости.

Еще одним решением MVCish может быть реализация привязки пользовательской модели (полностью непроверенная):

public override object BindModel(ControllerContext controllerContext,
    ModelBindingContext bindingContext)
        {
            var address = base.BindModel(controllerContext, bindingContext) as Address;
            if (bindingContext.ModelName.EndsWith("BillingAddress"))
            {
                foreach (PropertyInfo p in address.GetType().GetProperties())
                {
                Attribute a = Attribute.GetCustomAttribute(p, typeof(RequiredAttribute));
                if (a != null 
                    && propertyInfo.GetValue(address, null) == null 
                    && bindingContext.ModelState[bindingContext.ModelName 
                       + "." + p.Name].Errors.Count == 1)
                {
                    bindingContext.ModelState[bindingContext.ModelName + "." + p.Name].Errors.Clear();
                }
            }
            return address;
        }
...