Nice programing

MVC 모델에는 true가 필요합니다.

nicepro 2020. 10. 17. 12:23
반응형

MVC 모델에는 true가 필요합니다.


데이터 주석을 통해 부울 속성을 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
}

서버 측과 클라이언트 측 모두에 대한 유효성 검사기를 만들 것입니다. 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; }

마지막으로 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"
    };
}

나는 이것이 오래된 게시물이라는 것을 알고 있지만 이것을 수행하는 간단한 서버 측 방법을 공유하고 싶었습니다. 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; }

몇 가지 솔루션을 시도했지만 클라이언트 및 서버 측 유효성 검사를 모두 수행하는 데 완전히 효과가 없었습니다. 그래서 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; }

고유 한 속성을 만들거나 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]속성은 모든 값이 필요함을 의미 하며 true 또는 false 일 수 있습니다. 이를 위해 다른 유효성 검사를 사용해야합니다.


당신은이 있는가 의 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;}

에서 여기 .


들어 ASP.NET 코어 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; }

ta.speot.is의 게시물과 Jerad Rose의 댓글에 대한 후속 조치 :

주어진 게시물은 눈에 띄지 않는 유효성 검사로 클라이언트 측에서 작동하지 않습니다. 이것은 두 캠프 (클라이언트 및 서버)에서 작동합니다.

[RegularExpression("(True|true)")]
public bool TermsAndConditions { 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 +에서만 사용 가능).


이것이 나를 위해 일한 것입니다. 다른 것은 없습니다. 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


I think the best way to handle this is just check in your controller if the box is true otherwise just add an error to your model and have it redisplay your view.

As previously stated all [Required] does is make sure there is a value and in your case if not checked you still get false.


Check out Foolproof validation here. You can download/install it via Nuget.

It's a great little library for this kind of thing.


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

참고URL : https://stackoverflow.com/questions/4730183/mvc-model-require-true

반응형