Asp.net mvc 使用MVC DataAnnotationsModelValidatorProvider基于另一个属性应用所需的属性

Asp.net mvc 使用MVC DataAnnotationsModelValidatorProvider基于另一个属性应用所需的属性,asp.net-mvc,asp.net-mvc-4,data-annotations,Asp.net Mvc,Asp.net Mvc 4,Data Annotations,我有一个自定义元数据验证提供程序,如下所示 public class CustomMetadataValidationProvider : DataAnnotationsModelValidatorProvider { protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Att

我有一个自定义元数据验证提供程序,如下所示

public class CustomMetadataValidationProvider : DataAnnotationsModelValidatorProvider
{
    protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
    {
        //go to db if you want
        //var repository = ((MyBaseController) context.Controller).RepositorySomething;

        //find user if you need it
        var user = context.HttpContext.User;

        if (!string.IsNullOrWhiteSpace(metadata.PropertyName) && (metadata.PropertyName == "SelectedId" || metadata.PropertyName == "MultiSelectedIdList"))
            attributes = new List<Attribute>() { new RequiredAttribute() };

        return base.GetValidators(metadata, context, attributes);
    }

}
公共类CustomMetadataValidationProvider:DataAnnotationsModelValidationProvider { 受保护的重写IEnumerable GetValidator(ModelMetadata元数据、ControllerContext上下文、IEnumerable属性) { //如果需要,请转到db //var repository=((MyBaseController)context.Controller).RepositorySomething; //如果需要,请查找用户 var user=context.HttpContext.user; 如果(!string.IsNullOrWhiteSpace(metadata.PropertyName)&&(metadata.PropertyName==“SelectedId”| | metadata.PropertyName==“MultiSelectedIdList”)) 属性=新列表(){new RequiredAttribute()}; 返回base.GetValidators(元数据、上下文、属性); } } 这是我的模型

public class RelatedCategoryPartialModel
{
    public int RelatedCategoryTypeId { get; set; }
    public string RelatedCategoryTypeName { get; set; }
    public bool IsMultiSelect { get; set; }
    public bool IsRequired { get; set; }
    public int? SelectedId { get; set; }
    public IList<int> MultiSelectedIdList { get; set; }
    public IList<SelectListItem> RelatedCategoryTypeValueList { get; set; }
}
public class RelatedCategoryPartialModel
{
public int RelatedCategoryTypeId{get;set;}
公共字符串RelatedCategoryTypeName{get;set;}
公共bool IsMultiSelect{get;set;}
需要公共布尔值{get;set;}
public int?SelectedId{get;set;}
公共IList MultiselectedList{get;set;}
公共IList RelatedCategoryTypeValueList{get;set;}
}
我的问题是:我想对SelectedId和MultiSelectedList动态应用[Required]属性,但条件是必需的

这里的问题是,对于模型中的每个属性,它都经过CustomeMataValidationProvider,但是当metadat.property==“SelectedId”时,如何检查IsRequired值


那么我该怎么做呢,请建议……

我已经找到了自己的答案,但我想很高兴与大家分享

public class RequiredIfAttribute : RequiredAttribute
{
    private string PropertyName { get; set; }
    public string Emessage { get; set; }
    public string ControlValue { get; set; }
    public RequiredIfAttribute(string pName, string cName, String errormessage)
    {
        PropertyName = pName;
        Emessage = errormessage;
        ControlValue = cName;
    }

    protected override ValidationResult IsValid(object value, ValidationContext context)
    {
        Object instance = context.ObjectInstance;
        Type type = instance.GetType();
        Object proprtyvalue = type.GetProperty(PropertyName).GetValue(instance, null);
        object controlvalue = type.GetProperty(ControlValue).GetValue(instance, null);
        if (Convert.ToBoolean(proprtyvalue) && value == null)
        {
            return new ValidationResult(controlvalue + Emessage);
        }
        return ValidationResult.Success;
    }
}
这是viewmodel中的用法

public class RelatedCategoryPartialModel
{
    public int RelatedCategoryTypeId { get; set; }
    public string RelatedCategoryTypeName { get; set; }
    public bool IsMultiSelect { get; set; }
    public bool IsRequired { get; set; }
    [RequiredIf("IsRequired", "RelatedCategoryTypeName", " is required")]
    public int? SelectedId { get; set; }
    [RequiredIf("IsRequired", "RelatedCategoryTypeName", " is required")]
    public IList<int> MultiSelectedIdList { get; set; }
    public IList<SelectListItem> RelatedCategoryTypeValueList { get; set; }

}
public class RelatedCategoryPartialModel
{
public int RelatedCategoryTypeId{get;set;}
公共字符串RelatedCategoryTypeName{get;set;}
公共bool IsMultiSelect{get;set;}
需要公共布尔值{get;set;}
[RequiredIf(“IsRequired”、“RelatedCategoryTypeName”、“IsRequired”)]
public int?SelectedId{get;set;}
[RequiredIf(“IsRequired”、“RelatedCategoryTypeName”、“IsRequired”)]
公共IList MultiselectedList{get;set;}
公共IList RelatedCategoryTypeValueList{get;set;}
}
由于单个模型在视图中的两个不同列表(Dropdownlist和multi-select list)中有两个必需的属性,因此需要将0相应地设置为两个属性,如下所示

请注意,在渲染视图之前,需要通过选中IsMultiSelect来设置selectedId=0和MultiSelectedList=0

 @for (int i = 0; i < Model.Count(); i++)
                {
                    <div class="form-group">
                        <span class="col-xs-3">@Html.LabelFor(x => x[i].RelatedCategoryTypeName, Model[i].RelatedCategoryTypeName)</span>
                        @Html.HiddenFor(x => Model[i].RelatedCategoryTypeId)
                        @Html.HiddenFor(x => Model[i].IsMultiSelect)
                        @Html.HiddenFor(x => Model[i].IsRequired)
                        @Html.HiddenFor(x => Model[i].RelatedCategoryTypeName)
                        <div class="row">
                            @if (Model[i].IsMultiSelect)
                            {
                                <div class="col-xs-3">@Html.ListBoxFor(b => Model[i].MultiSelectedIdList, Model[i].RelatedCategoryTypeValueList, new { @id = Model[i].RelatedCategoryTypeValueList, @class = "form-control .ch" })</div>
                                <div class="col-xs-4">@Html.ValidationMessageFor(x => x[i].MultiSelectedIdList)</div>

                                @Html.HiddenFor(x => Model[i].SelectedId)
                            }
                            else
                            {
                                <div class="col-xs-3">@Html.DropDownListFor(a => Model[i].SelectedId, Model[i].RelatedCategoryTypeValueList, "--- Please select ---", new { @id = Model[i].RelatedCategoryTypeValueList, @class = "form-control" })</div>
                                <div class="col-xs-4">@Html.ValidationMessageFor(x => x[i].SelectedId)</div>


                                for (int x = 0; x < Model[i].MultiSelectedIdList.Count; x++)
                                {
                                    @Html.HiddenFor(c => Model[i].MultiSelectedIdList[x])
                                }



                            }
                        </div>

                    </div>
                }
for(int i=0;ix[i]。RelatedCategoryTypeName,模型[i]。RelatedCategoryTypeName) @Html.HiddenFor(x=>Model[i].RelatedCategoryTypeId) @Html.HiddenFor(x=>Model[i].IsMultiSelect) @Html.HiddenFor(x=>Model[i].IsRequired) @Html.HiddenFor(x=>Model[i].RelatedCategoryTypeName) @if(型号[i].IsMultiSelect) { @Html.ListBoxFor(b=>Model[i]。多选数据列表,Model[i]。RelatedCategoryTypeValueList,新的{@id=Model[i]。RelatedCategoryTypeValueList,@class=“form control.ch”}) @Html.ValidationMessageFor(x=>x[i].MultiselectedList) @Html.HiddenFor(x=>Model[i].SelectedId) } 其他的 { @Html.DropDownListFor(a=>Model[i]。SelectedId,Model[i]。RelatedCategoryTypeValueList,“---请选择---”,新建{@id=Model[i]。RelatedCategoryTypeValueList,@class=“form control”}) @Html.ValidationMessageFor(x=>x[i].SelectedId) 对于(int x=0;xModel[i].MultiSelectedIdList[x]) } } } 如果有人需要更多的见解,请发表评论。很乐意帮忙