Сегодня это работает. Можете ли вы быть уверены, что он будет работать через 5, 10 лет? Эти вопросы и ответы созданы для будущих пользователей.

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

public class MyAwesomeObj{
    public bool ThisMustBeTrue{get;set;}
}
 PsychoCoder19 янв. 2011 г., 02:24
Я думаю, что это то, что вы хотели бы решить на стороне клиента.
 Marty Trenouth19 янв. 2011 г., 00:35
Это довольно много сказать ... эй, приятель, ты забыл проверить, я согласен ... что должно сделать модель недействительной.
 Marty Trenouth19 янв. 2011 г., 02:40
@PsychoCoder: он должен обрабатываться с обеих сторон, а не только со стороны клиента. Я просто искал, можно ли это сделать, добавив простую аннотацию данных.
 Jan Thomä19 янв. 2011 г., 00:29
Какой именно это вариант использования? Не могли бы вы просто позволить свойству быть доступным только для чтения и возвращать true все время?

Ответы на вопрос(16)

За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; }

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);
    }
}

соответствующие элементы, настроенные в web.config?

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

Вы также можете попробовать создать собственный атрибут проверки (так как[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;}

ИзВот.

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

но ни одно из них не помогло мне полностью пройти проверку на стороне клиента и на стороне сервера. Итак, что я сделал в своем приложении 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>
 Tobias25 окт. 2017 г., 14:55
Позаботьтесь о значении скрытого поля («true»)!
 Tobias25 окт. 2017 г., 14:50
Очаровательное решение!
Решение Вопроса

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
}
 T-moty03 апр. 2017 г., 12:30
return (bool) value == true; это избыточное сравнение
 Jitendra Pancholi30 янв. 2014 г., 11:46
Это не работает.
 SamStephens11 окт. 2011 г., 00:22
Я бы подумал об улучшении этого с помощью реализации на стороне клиента - вместо использования удаленной проверки, упомянутой в других ответах, используйте ненавязчивое, изложенное здесь:jacopretorius.net/2011/01/client-side-validation-in-mvc-3.html
 Seth30 мая 2013 г., 19:41
Это хорошее (и проверенное) быстрое решение для нас. Мы можем обойтись без проверки на стороне клиента в решении @ dazbradbury (что тоже неплохо), потому что нам это нужно только в виде одиночного флажка на последней странице опроса.
/// <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 } };
    }
}
 Eliyahu31 дек. 2014 г., 16:41
Сегодня это работает. Можете ли вы быть уверены, что он будет работать через 5, 10 лет? Эти вопросы и ответы созданы для будущих пользователей.
 dhandapani harikrishnan31 дек. 2014 г., 11:02
Это работает Проверьте эту ссылку с указанием причины, по которой она не проходит проверку.itmeze.com/2010/12/06/...
 Ravi Dhoriya ツ31 дек. 2014 г., 10:30
Хотя эта ссылка может ответить на вопрос, лучше включить сюда основные части ответа и предоставить ссылку для справки. Ответы, содержащие только ссылки, могут стать недействительными в случае изменения связанной страницы.

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

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

модель

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" })

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

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

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

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

 Pangamma05 апр. 2018 г., 21:29
Эхххх ... Хотя атрибуты проверки по умолчанию работают довольно хорошо.

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.");
    }
  }

но это легко сделать в вашем контроллере.

public ActionResult Add(Domain.Something model)
{

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

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

}

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

 Marty Trenouth19 янв. 2011 г., 00:49
Вроде уже новенький, как проверить логический флаг уже .... хотел узнать, есть ли для него аннотации данных.

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

[RegularExpression("True")]
public bool TermsAndConditions { get; set; }
 ta.speot.is17 янв. 2014 г., 06:22
@JeradRose На сервере все отлично проверяется. Вы имеете в виду проверку на стороне клиента?
 Jerad Rose17 янв. 2014 г., 05:23
Это не будет работать для проверки на стороне сервера, правда?
 ta.speot.is17 янв. 2014 г., 14:34
RegularExpressionAttribute внутренне используетConvert.ToString чтобы получить строковое представление значения свойства (которое доставляется ему какobject).
 Matt Frear17 янв. 2014 г., 12:27
Подтверждено, что это работает на стороне сервера, но не на стороне клиента
 Jerad Rose17 янв. 2014 г., 14:04
Я думал, что проверка на стороне сервера может иметь исключение несоответствия типов при попытке сравнить bool со строкой.

что это старый пост, но хотел бы поделиться простым серверным способом сделать это. Вы создаете частное свойство со значением true и сравниваете значение bool с этим свойством. Если ваш 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; }
 Jeremy A. West05 июн. 2014 г., 21:51
+1 за нестандартное мышление, просто и чисто, обожаю!
 Tod Birdsall14 окт. 2014 г., 18:42
+1 для простоты. К вашему сведению: я должен был сделать свойство isTrue публичным, чтобы это работало.
 billoreid07 сент. 2016 г., 20:55
И если вы добавите скрытое свойство isTrue, вы получите проверку на стороне клиента
 Michael Rudner Evanchik19 мар. 2015 г., 19:03
Сравнить не для меня в MVC4
 David15 мая 2015 г., 07:44
@CutRateGamer, я отредактировал ответ, чтобы isTrue был публичным.

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([email protected]"Error Message")]
public bool ThisMustBeTrue{ get; set; }

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

<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"
    };
}
 Matt Frear17 янв. 2014 г., 13:19
Спасибо за это - это прекрасно работает! Он работает лучше с удаленным методом переопределения FormatErrorMessage - так работает локализация сообщений об ошибках из файлов ресурсов. Мое использование: [EnforceTrue (ErrorMessageResourceType = typeof (ValidationMessages), ErrorMessageResourceName = "TermsAndConditionsRequired")]
 jeepwran10 дек. 2014 г., 18:45
Отличное решение, демонстрирующее силу пользовательских атрибутов проверки! Хотя я рекомендую поместить скрипт в js-файл с глобальными ссылками, а не в представления для повторного использования. Кроме того, лучше всего обрабатывать все способы, которыми могут быть добавлены строки сообщения: по умолчанию, если ничего не указано, или строка сообщения, или из файла ресурсов.
 vsdev30 янв. 2014 г., 11:09
Я не могу заставить работать проверку на стороне клиента и не могу сказать, что я делаю неправильно. Где именно я должен поставить JavaScript? В голове тег? Рядом с контроллером?
 Jitendra Pancholi30 янв. 2014 г., 11:45
Потрясающие. Это должно быть отмечено как ответ.
 Evert17 сент. 2015 г., 23:51
Отличное решение, спасибо за публикацию. Для тех, кто не может заставить работать на стороне клиента: Вы должны расширить проверку jQuery до того, как будут загружены проверяемые элементы управления, поэтому поместите скрипт в заголовок, а не в window.onload / $ (document ) .ready () событие.

Ваш ответ на вопрос