使用MVC DataAnnotationsModelValidatorProvider根据另一个属性应用所需的属性

时间:2015-03-09 00:32:25

标签: asp.net-mvc asp.net-mvc-4 data-annotations

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

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

}

这是我的模特

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

我的问题是:我想动态地将[Required]属性应用于SelectedId和MultiSelectedIdList,但条件是IsRequired。

这里的问题是我的模型中的每个属性都通过customeMetadataValidationProvider,但是如何在metadat.property ==“SelectedId”时检查IsRequired值

那我怎么能这样做,请指教......

1 个答案:

答案 0 :(得分:0)

我找到了自己的答案,但认为与大家分享很高兴

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

}

由于单个模型在视图中具有两个不同列表(下拉列表和多选列表)的两个必需属性,因此您需要相应地将0设置为0,如下所示。

请在渲染视图之前注意,您需要通过选中IsMultiSelect

来设置selectedId = 0和MultiSelectedIdList = 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>
                }

如果有人需要更多见解,请发表评论。很高兴帮忙!!!