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