Модель MVC требует true



есть ли способ через аннотации данных требовать, чтобы логическое свойство было установлено в true?



public class MyAwesomeObj{
public bool ThisMustBeTrue{get;set;}
}
542   16  

16 ответов:

вы можете создать свой собственный валидатор:

public class IsTrueAttribute : ValidationAttribute
{
    #region Overrides of ValidationAttribute

    /// <summary>
    /// Determines whether the specified value of the object is valid. 
    /// </summary>
    /// <returns>
    /// true if the specified value is valid; otherwise, false. 
    /// </returns>
    /// <param name="value">The value of the specified validation object on which the <see cref="T:System.ComponentModel.DataAnnotations.ValidationAttribute"/> is declared.
    ///                 </param>
    public override bool IsValid(object value)
    {
        if (value == null) return false;
        if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");

        return (bool) value;
    }

    #endregion
}

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

во-первых, создайте класс в своем проекте для выполнения проверки на стороне сервера следующим образом:

public class EnforceTrueAttribute : ValidationAttribute, IClientValidatable
{
    public override bool IsValid(object value)
    {
        if (value == null) return false;
        if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");
        return (bool)value == true;
    }

    public override string FormatErrorMessage(string name)
    {
        return "The " + name + " field must be checked in order to continue.";
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        yield return new ModelClientValidationRule
        {
            ErrorMessage = String.IsNullOrEmpty(ErrorMessage) ? FormatErrorMessage(metadata.DisplayName) : ErrorMessage,
            ValidationType = "enforcetrue"
        };
    }
}

после этого, аннотировать соответствующее свойство в вашей модели:

[EnforceTrue(ErrorMessage=@"Error Message")]
public bool ThisMustBeTrue{ get; set; }

и, наконец, включите проверку на стороне клиента, добавив следующий скрипт в свой Вид:

<script type="text/javascript">
    jQuery.validator.addMethod("enforcetrue", function (value, element, param) {
        return element.checked;
    });
    jQuery.validator.unobtrusive.adapters.addBool("enforcetrue");
</script>

Примечание: мы уже создали метод GetClientValidationRules что подталкивает нашу аннотацию к виду из нашей модели.

при использовании файлов ресурсов для предоставления сообщения об ошибке для интернационализации удалите FormatErrorMessage вызов (или просто вызов базы) и настроить GetClientValidationRules метод вот так:

public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
    string errorMessage = String.Empty;
    if(String.IsNullOrWhiteSpace(ErrorMessage))
    {
        // Check if they supplied an error message resource
        if(ErrorMessageResourceType != null && !String.IsNullOrWhiteSpace(ErrorMessageResourceName))
        {
            var resMan = new ResourceManager(ErrorMessageResourceType.FullName, ErrorMessageResourceType.Assembly);
            errorMessage = resMan.GetString(ErrorMessageResourceName);
        }
    }
    else
    {
        errorMessage = ErrorMessage;
    }

    yield return new ModelClientValidationRule
    {
        ErrorMessage = errorMessage,
        ValidationType = "enforcetrue"
    };
}

Я знаю, что это более старый пост, но хотел поделиться простым способом на стороне сервера, чтобы сделать это. Вы создаете частное свойство, равное true, и сравниваете свой bool с этим свойством. Если ваш тип не установлен (по умолчанию false) форма не будет проверять.

public bool isTrue
{ get { return true; } }

[Required]
[Display(Name = "I agree to the terms and conditions")]
[Compare("isTrue", ErrorMessage = "Please agree to Terms and Conditions")]
public bool iAgree { get; set; }

я попробовал несколько решений, но ни одно из них не работало полностью для меня, чтобы получить как клиентскую, так и серверную проверку. Итак, что я сделал в своем приложении MVC 5, чтобы заставить его работать:

в ViewModel (для проверки на стороне сервера):

public bool IsTrue => true;

[Required]
[Display(Name = "I agree to the terms and conditions")]
[Compare(nameof(IsTrue), ErrorMessage = "Please agree to Terms and Conditions")]
public bool HasAcceptedTermsAndConditions { get; set; }

на странице Razor (для проверки на стороне клиента):

<div class="form-group">
   @Html.CheckBoxFor(m => m.HasAcceptedTermsAndConditions)
   @Html.LabelFor(m => m.HasAcceptedTermsAndConditions)
   @Html.ValidationMessageFor(m => m.HasAcceptedTermsAndConditions)

   @Html.Hidden(nameof(Model.IsTrue), "true")
</div>

Я просто хотел бы направить людей на следующую скрипку:https://dotnetfiddle.net/JbPh0X

пользователь добавлен [Range(typeof(bool), "true", "true", ErrorMessage = "You gotta tick the box!")] к их логическому свойству, которое вызывает проверку на стороне сервера для работы.

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

// extend jquery range validator to work for required checkboxes
var defaultRangeValidator = $.validator.methods.range;
$.validator.methods.range = function(value, element, param) {
    if(element.type === 'checkbox') {
        // if it's a checkbox return true if it is checked
        return element.checked;
    } else {
        // otherwise run the default validation function
        return defaultRangeValidator.call(this, value, element, param);
    }
}

Вы можете либо создать свой собственный атрибут или использовать CustomValidationAttribute.

вот как вы будете использовать CustomValidationAttribute:

[CustomValidation(typeof(BoolValidation), "ValidateBool")]

где BoolValidation определяется как:

public class BoolValidation
{
  public static ValidationResult ValidateBool(bool boolToBeTrue)
  {
    if (boolToBeTrue)
    {
      return ValidationResult.Success;
    }
    else
    {
      return new ValidationResult(
          "Bool must be true.");
    }
  }

просто проверьте, равно ли его строковое представление True:

[RegularExpression("True")]
public bool TermsAndConditions { get; set; }

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

у вас есть соответствующие элементы, настроенные в интернете.конфигурации?

Это может привести к тому, что проверка не будет работать.

вы также можете попробовать создать пользовательский атрибут проверки (так как [Required] только заботится о том, существует ли он, и вы заботитесь о значении):

[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
sealed public class RequiredTrueAttribute : ValidationAttribute
{
    // Internal field to hold the mask value.
    readonly bool accepted;

    public bool Accepted
    {
        get { return accepted; }
    }

    public RequiredTrueAttribute(bool accepted)
    {
        this.accepted = accepted;
    }

    public override bool IsValid(object value)
    {
        bool isAccepted = (bool)value;
        return (isAccepted == true);
    }

    public override string FormatErrorMessage(string name)
    {
        return String.Format(CultureInfo.CurrentCulture,
          ErrorMessageString, name, this.Accepted);
    }
}

затем, использование:

[RequiredTrue(ErrorMessage="{0} requires acceptance to continue.")]
public bool Agreement {get; set;}

С здесь.

для ASP.NET Core MVC вот проверка клиента и сервера, основанная на решении dazbradbury

public class EnforceTrueAttribute : ValidationAttribute, IClientModelValidator
{
    public override bool IsValid(object value)
    {
        if (value == null) return false;
        if (value.GetType() != typeof(bool)) throw new InvalidOperationException("can only be used on boolean properties.");
        return (bool)value;
    }

    public void AddValidation(ClientModelValidationContext context)
    {
        MergeAttribute(context.Attributes, "data-val", "true");
        var errorMessage = ErrorMessage ?? 
            $"The value for field {context.ModelMetadata.GetDisplayName()} must be true.";
        MergeAttribute(context.Attributes, "data-val-enforcetrue", errorMessage);
    }

    private void MergeAttribute(IDictionary<string, string> attributes,
        string key,
        string value)
    {
        if (attributes.ContainsKey(key))
        {
            return;
        }
        attributes.Add(key, value);
    }
}

а потом на клиенте:

$.validator.addMethod("enforcetrue", function (value, element, param) {
    return element.checked;
});

$.validator.unobtrusive.adapters.addBool("enforcetrue");

затем использование:

[EnforceTrue(ErrorMessage = "Please tick the checkbox")]
public bool IsAccepted { get; set; }

Я не знаю пути через DataAnnotations, но это легко сделать в вашем контроллере.

public ActionResult Add(Domain.Something model)
{

    if (!model.MyCheckBox)
        ModelState.AddModelError("MyCheckBox", "You forgot to click accept");

    if (ModelState.IsValid) {
        //'# do your stuff
    }

}

единственным другим вариантом было бы построить пользовательский валидатор для стороны сервера и удаленный оценщик для клиентской стороны (удаленная проверка доступна только в MVC3+)

продолжение поста ta.speot.is и комментарий от Джерада Роуза:

данный пост не будет работать на стороне клиента с ненавязчивой валидации. Это должно работать в обоих лагерях:

[RegularExpression("(True|true")]
public bool TermsAndConditions { get; set; }

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

Как было указано ранее все [требуется] делает это убедитесь, что есть значение и в вашем случае, если не проверено вы все равно получите false.

Проверьте надежную проверку здесь. Вы можете скачать / установить его через Nuget.

Это отличная маленькая библиотека для такого рода вещей.

это то, что работал для меня. Больше ничего не случилось. Mvc 5:

модель

public string True
{
  get
  {
    return "true";
  }
}

[Required]
[Compare("True", ErrorMessage = "Please agree to the Acknowlegement")]
public bool Acknowlegement { get; set; }

посмотреть

  @Html.HiddenFor(m => m.True)
  @Html.EditorFor(model => model.Acknowlegement, new { htmlAttributes = Model.Attributes })
  @Html.ValidationMessageFor(model => model.Acknowlegement, "", new { @class = "text-danger" })

enter image description here

enter image description here

/// <summary> 
///  Summary : -CheckBox for or input type check required validation is not working the root cause and solution as follows
///
///  Problem :
///  The key to this problem lies in interpretation of jQuery validation 'required' rule. I digged a little and find a specific code inside a jquery.validate.unobtrusive.js file:
///  adapters.add("required", function (options) {
///  if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") {
///    setValidationValues(options, "required", true);
///    }
///   });
///   
///  Fix: (Jquery script fix at page level added in to check box required area)
///  jQuery.validator.unobtrusive.adapters.add("brequired", function (options) {
///   if (options.element.tagName.toUpperCase() == "INPUT" && options.element.type.toUpperCase() == "CHECKBOX") {
///              options.rules["required"] = true;
///   if (options.message) {
///                   options.messages["required"] = options.message;
///                       }
///  Fix : (C# Code for MVC validation)
///  You can see it inherits from common RequiredAttribute. Moreover it implements IClientValidateable. This is to make assure that rule will be propagated to client side (jQuery validation) as well.
///  
///  Annotation example :
///   [BooleanRequired]
///   public bool iAgree { get; set' }
/// </summary>


public class BooleanRequired : RequiredAttribute, IClientValidatable
{

    public BooleanRequired()
    {
    }

    public override bool IsValid(object value)
    {
        return value != null && (bool)value == true;
    }

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        return new ModelClientValidationRule[] { new ModelClientValidationRule() { ValidationType = "brequired", ErrorMessage = this.ErrorMessage } };
    }
}

Comments

    Ничего не найдено.