มีวิธีผ่านคำอธิบายประกอบข้อมูลเพื่อกำหนดให้คุณสมบัติบูลีนถูกตั้งค่าเป็น true หรือไม่?
public class MyAwesomeObj{
public bool ThisMustBeTrue{get;set;}
}
มีวิธีผ่านคำอธิบายประกอบข้อมูลเพื่อกำหนดให้คุณสมบัติบูลีนถูกตั้งค่าเป็น true หรือไม่?
public class MyAwesomeObj{
public bool ThisMustBeTrue{get;set;}
}
คำตอบ:
คุณสามารถสร้างตัวตรวจสอบความถูกต้องของคุณเอง:
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
}
return (bool) value == true;
นี่เป็นการเปรียบเทียบที่ซ้ำซ้อน
ฉันจะสร้างตัวตรวจสอบความถูกต้องสำหรับทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์ การใช้ 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"
};
}
ฉันรู้ว่านี่เป็นโพสต์ที่เก่ากว่า แต่ต้องการแบ่งปันวิธีง่ายๆทางฝั่งเซิร์ฟเวอร์ในการทำเช่นนี้ คุณสร้างคุณสมบัติสาธารณะที่ตั้งค่าเป็นจริงและเปรียบเทียบบูลของคุณกับคุณสมบัตินั้น หากไม่ได้ตรวจสอบบูลของคุณ (โดยค่าเริ่มต้นเป็นเท็จ) แบบฟอร์มจะไม่ตรวจสอบความถูกต้อง
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 AgreeTerms { get; set; }
รหัสมีดโกน
@Html.CheckBoxFor(m => Model.AgreeTerms, new { id = "AgreeTerms", @checked = "checked" })
<label asp-for="AgreeTerms" class="control-label"></label>
<a target="_blank" href="/Terms">Read</a>
<br />
@Html.ValidationMessageFor(model => model.AgreeTerms, "", new { @class = "text-danger" })
@Html.HiddenFor(x => Model.isTrue)
ฉันลองใช้วิธีแก้ปัญหาหลายวิธี แต่ไม่มีวิธีใดที่ใช้ได้ผลอย่างสมบูรณ์สำหรับฉันในการรับการตรวจสอบความถูกต้องทั้งฝั่งไคลเอ็นต์และเซิร์ฟเวอร์ สิ่งที่ฉันทำในแอปพลิเคชัน 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>
ฉันแค่อยากจะแนะนำผู้คนไปยัง Fiddle ต่อไปนี้: 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);
}
}
เพียงตรวจสอบเพื่อดูว่าการแทนค่าสตริงเท่ากับTrue
:
[RegularExpression("True")]
public bool TermsAndConditions { get; set; }
RegularExpressionAttribute
ใช้ภายในConvert.ToString
เพื่อรับการแสดงสตริงของค่าคุณสมบัติ (ซึ่งจะถูกส่งไปยังค่านี้เป็นobject
)
คุณจะสามารถสร้างแอตทริบิวต์ของคุณเองหรือใช้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.");
}
}
[Required]
แอตทริบิวต์หมายถึงการกำหนดค่าใด ๆ - อาจเป็นจริงหรือเท็จก็ได้ คุณต้องใช้การตรวจสอบความถูกต้องอื่นสำหรับสิ่งนั้น
สำหรับ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; }
$document.ready()
/ $(function() { });
"
required
แอตทริบิวต์ในอินพุต HTML เช่น<input asp-for="..." class="..." id="..." type="checkbox" required/>
ติดตามโพสต์โดย ta.speot.is และความคิดเห็นจากเจอราดโรส:
โพสต์ที่ระบุจะไม่ทำงานในฝั่งไคลเอ็นต์ด้วยการตรวจสอบความถูกต้องที่ไม่เป็นการรบกวน สิ่งนี้ควรใช้ได้ในทั้งสองค่าย (ไคลเอนต์และเซิร์ฟเวอร์):
[RegularExpression("(True|true)")]
public bool TermsAndConditions { get; set; }
regex
วิธีที่ไม่สร้างความรำคาญให้กำหนดขั้นแรกให้ตรวจสอบว่าช่องทำเครื่องหมายนั้นเป็นทางเลือกหรือไม่ก่อนที่จะตรวจสอบ regex ซึ่งเหมาะสมยกเว้นว่า jquery.validate ดูเหมือนจะพิจารณาว่าช่องทำเครื่องหมายที่ไม่ได้เลือกไว้เป็นทางเลือก tl; dr มันเรียกใช้ regex ในช่องทำเครื่องหมายที่เลือกเท่านั้น เราสามารถเพิ่ม shim สำหรับregex
validator
วิธีการหรือเพียงแค่สร้างตัวตรวจสอบที่กำหนดเอง
.NET Core MVC - ช่องทำเครื่องหมายที่จำเป็นพร้อมคำอธิบายประกอบข้อมูล
public class MyModel
{
[Display(Name = "Confirmation")]
[Range(typeof(bool), "true", "true", ErrorMessage = "Please check the Confirmation checkbox.")]
public bool IsConfirmed { get; set; }
}
<div class="custom-control custom-checkbox col-10">
<input type="checkbox" asp-for="IsConfirmed" class="custom-control-input" />
<label class="custom-control-label" for="IsConfirmed">
"By clicking 'submit', I confirm."
</label>
<span asp-validation-for="IsConfirmed" class="text-danger"></span>
</div>
<script src="~/lib/jquery-validation/dist/jquery.validate.js"></script>
<script src="~/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
<script type="text/javascript">
$(document).ready(function () {
// extend range validator method to treat checkboxes differently
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);
}
}
});
</script>
ฉันไม่รู้วิธีผ่าน 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 +)
คุณมีรายการที่เหมาะสมตั้งค่าใน 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;}
จากที่นี่ .
นี่คือสิ่งที่ได้ผลสำหรับฉัน ไม่มีอะไรทำ เอ็มวีซี 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" })
ฉันพยายามใช้คำตอบของ fields.cage และมันก็ไม่ได้ผลสำหรับฉัน แต่มีบางอย่างที่ง่ายกว่าและฉันไม่แน่ใจว่าทำไม (อาจจะเป็นรุ่น Razor ที่แตกต่างกัน) แต่สิ่งที่ฉันต้องทำก็คือ:
[Required]
[Range(typeof(bool), "true", "true", ErrorMessage = "Agreement required.")]
[Display(Name = "By clicking here, I agree that my firstborn child will etc etc...")]
public bool Agreement1Checked { get; set; }
และในไฟล์. cshtml:
@Html.CheckBoxFor(m => m.Agreement1Checked)
@Html.LabelFor(m => m.Agreement1Checked)
@Html.ValidationMessageFor(m => m.Agreement1Checked)
[NaN, NaN]
ที่ที่ควรจะเป็น[true, true]
ฉันคิดว่าวิธีที่ดีที่สุดในการจัดการสิ่งนี้คือเพียงตรวจสอบในคอนโทรลเลอร์ของคุณว่ากล่องนั้นเป็นจริงหรือไม่เพียงแค่เพิ่มข้อผิดพลาดให้กับโมเดลของคุณและให้มันแสดงมุมมองของคุณอีกครั้ง
ตามที่ระบุไว้ก่อนหน้านี้ [จำเป็น] ทั้งหมดคือตรวจสอบให้แน่ใจว่ามีค่าและในกรณีของคุณหากไม่ได้ตรวจสอบคุณยังคงได้รับเท็จ
/// <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 } };
}
}