Отключить обязательный атрибут проверки при определенных обстоятельствах - PullRequest
122 голосов
/ 20 марта 2011

Мне было интересно, возможно ли отключить обязательный атрибут проверки в определенных действиях контроллера.Мне интересно это, потому что в одной из моих форм редактирования я не требую, чтобы пользователь вводил значения для полей, которые они уже указали ранее.Однако затем я реализую логику, что, когда они вводят значение, он использует некоторую специальную логику для обновления модели, такую ​​как хеширование значения и т. Д.

Любые предположения о том, как обойти эту проблему?

РЕДАКТИРОВАТЬ:И да, здесь проблема с проверкой клиента, так как она не позволит им отправить форму без ввода значения.

Ответы [ 16 ]

1 голос
/ 08 января 2018

Начиная с MVC 5, этого легко достичь, добавив это в global.asax.

DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;
1 голос
/ 12 июня 2013

То, что сказал @ Darin, я бы тоже порекомендовал. Однако я хотел бы добавить к этому (и в ответ на один из комментариев), что вы также можете использовать этот метод для примитивных типов, таких как bit, bool, и даже структур, таких как Guid, просто сделав их обнуляемыми. Как только вы сделаете это, атрибут Required будет функционировать как положено.

public UpdateViewView
{
    [Required]
    public Guid? Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Required]
    public int? Age { get; set; }
    [Required]
    public bool? IsApproved { get; set; }
    //... some other properties
}
1 голос
/ 20 марта 2011

AFAIK Вы не можете удалять атрибуты во время выполнения, а только изменять их значения (то есть: только для чтения true / false) ищите здесь что-то похожее .В качестве другого способа сделать то, что вы хотите, не связываясь с атрибутами, я воспользуюсь ViewModel для вашего конкретного действия, чтобы вы могли вставить всю логику, не нарушая логику, необходимую для других контроллеров.Если вы попытаетесь получить какой-нибудь мастер (многошаговую форму), вы можете вместо этого сериализовать уже скомпилированные поля и с помощью TempData перенести их в ваши шаги.(для помощи в сериализации десериализации вы можете использовать MVC фьючерсы )

0 голосов
/ 31 мая 2019

В моем случае одна и та же Модель использовалась на многих страницах для повторного использования.Так что я сделал, я создал собственный атрибут, который проверяет исключения

public class ValidateAttribute : ActionFilterAttribute
{
    public string Exclude { get; set; }
    public string Base { get; set; }
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        if (!string.IsNullOrWhiteSpace(this.Exclude))
        {
            string[] excludes = this.Exclude.Split(',');
            foreach (var exclude in excludes)
            {
                actionContext.ModelState.Remove(Base + "." + exclude);
            }
        }
        if (actionContext.ModelState.IsValid == false)
        {
            var mediaType = new MediaTypeHeaderValue("application/json");
            var error = actionContext.ModelState;

            actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.OK, error.Keys, mediaType);

        }
    }
}

и в вашем контроллере

[Validate(Base= "person",Exclude ="Age,Name")]
    public async Task<IHttpActionResult> Save(User person)
    {

            //do something           

    }

Скажем, модель

public class User
{
    public int Id { get; set; }
    [Required]
    public string Name { get; set; }
    [Range(18,99)]
    public string Age { get; set; }
    [MaxLength(250)]
    public string Address { get; set; }
}
0 голосов
/ 15 марта 2016

Да, можно отключить обязательный атрибут. Создайте свой собственный атрибут класса (пример кода с именем ChangeableRequired) для экстента из RequiredAtribute, добавьте свойство Disabled и переопределите метод IsValid, чтобы проверить, отключен ли он. Используйте рефлексию, чтобы установить отключенный poperty, например:

Пользовательский атрибут:

namespace System.ComponentModel.DataAnnotations
{
    public class ChangeableRequired : RequiredAttribute
    {
       public bool Disabled { get; set; }

       public override bool IsValid(object value)
       {
          if (Disabled)
          {
            return true;
          }

          return base.IsValid(value);
       }
    }
}

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

 class Forex
 {
 ....
    [ChangeableRequired]
    public decimal? ExchangeRate {get;set;}
 ....
 }

, где вам нужно отключить свойство, используйте его отражение:

Forex forex = new Forex();
// Get Property Descriptor from instance with the Property name
PropertyDescriptor descriptor = TypeDescriptor.GetProperties(forex.GetType())["ExchangeRate"];
//Search for Attribute
ChangeableRequired attrib =  (ChangeableRequired)descriptor.Attributes[typeof(ChangeableRequired)];

// Set Attribute to true to Disable
attrib.Disabled = true;

Это приятно и чисто?

NB. Приведенная выше проверка будет отключена, пока экземпляр вашего объекта жив \ active ...

0 голосов
/ 06 марта 2013

Если вы не хотите использовать другую ViewModel, вы можете отключить проверки клиента в представлении, а также удалить проверки на сервере для тех свойств, которые вы хотите игнорировать.Пожалуйста, проверьте этот ответ для более глубокого объяснения https://stackoverflow.com/a/15248790/1128216

...