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;i