C# MVC3 ValidationAttribute validationContext.memberName为null

C# MVC3 ValidationAttribute validationContext.memberName为null,c#,asp.net,visual-studio,asp.net-mvc-3,validation,C#,Asp.net,Visual Studio,Asp.net Mvc 3,Validation,我到处都能找到半个解决方案,但我找不到真正的答案 我已经创建了一个从ValidationAttribute和IClientValidable继承的验证属性 一切似乎都很正常,如果我在页面上放置验证摘要,则会显示错误 但是,我无法在与属性相关的文本框旁边显示错误 我认为这是因为我需要将属性名称添加到验证结果中 但是,这就是它失败的地方,因为我无法从validationContext获取成员名称 有没有办法让这种情况发生?还是我遗漏了什么 public class AdmissionDayCaseA

我到处都能找到半个解决方案,但我找不到真正的答案

我已经创建了一个从ValidationAttribute和IClientValidable继承的验证属性

一切似乎都很正常,如果我在页面上放置验证摘要,则会显示错误

但是,我无法在与属性相关的文本框旁边显示错误

我认为这是因为我需要将属性名称添加到验证结果中

但是,这就是它失败的地方,因为我无法从validationContext获取成员名称

有没有办法让这种情况发生?还是我遗漏了什么

public class AdmissionDayCaseAttribute : ValidationAttribute, IClientValidatable
{
    private String DayCaseID;
    private String AdmissionDateID;
    private String DischargeDateID;

    public AdmissionDayCaseAttribute(String DayCaseID, String AdmissionDateID, String DischargeDateID)
    {
        this.DayCaseID = DayCaseID;
        this.AdmissionDateID = AdmissionDateID;
        this.DischargeDateID = DischargeDateID;
    }
    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        object AdmissionDate = GetPropertyValue(validationContext.ObjectInstance, AdmissionDateID);
        object DischargeDate = GetPropertyValue(validationContext.ObjectInstance, DischargeDateID);
        object AdmissionType = validationContext.MemberName == null ? null : GetPropertyValue(validationContext.ObjectInstance, validationContext.MemberName);
        if (AdmissionDate != null && DischargeDate != null && AdmissionType != null)
        {
            if (AdmissionDate.Equals(DischargeDate) && DayCaseID.Equals(AdmissionType.ToString()))
            {
                return new ValidationResult(ErrorMessage, new List<String>() { validationContext.MemberName });
            }
        }
        return ValidationResult.Success;
    }
    private object GetPropertyValue(object instance,String propertyName)
    {
        Type itype = instance.GetType();
        return itype.GetProperty(propertyName).GetValue(instance,null);
    }
    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ModelClientValidationRule vr = new ModelClientValidationRule()
        {
            ErrorMessage = ErrorMessage,
            ValidationType = "admissiondaycase"
        };
        vr.ValidationParameters.Add(new KeyValuePair<string, object>("admissiondateid", AdmissionDateID));
        vr.ValidationParameters.Add(new KeyValuePair<string, object>("dischargedateid", DischargeDateID));
        vr.ValidationParameters.Add(new KeyValuePair<string, object>("daycaseid", DayCaseID));
        yield return vr;
    }
public类AdmissionDayCaseAttribute:ValidationAttribute,IClientValidable
{
私有字符串DayCaseID;
私有字符串AdmissionDateID;
私有字符串dischargedTeID;
public AdmissionDayCaseAttribute(字符串DayCaseID、字符串AdmissionDateID、字符串DischargeDateID)
{
this.DayCaseID=DayCaseID;
this.AdmissionDateID=AdmissionDateID;
this.dischargedTeId=dischargedTeId;
}
受保护的重写ValidationResult有效(对象值,ValidationContext ValidationContext)
{
object AdmissionDate=GetPropertyValue(validationContext.ObjectInstance,AdmissionDateID);
object DischargeDate=GetPropertyValue(validationContext.ObjectInstance,DischargeDateID);
对象许可类型=validationContext.MemberName==null?null:GetPropertyValue(validationContext.ObjectInstance,validationContext.MemberName);
if(许可日期!=null&&DischargeDate!=null&&AdmissionType!=null)
{
if(AdmissionDate.Equals(DischargeDate)和&DayCaseID.Equals(AdmissionType.ToString())
{
返回新的ValidationResult(ErrorMessage,new List(){validationContext.MemberName});
}
}
返回ValidationResult.Success;
}
私有对象GetPropertyValue(对象实例,字符串propertyName)
{
键入itype=instance.GetType();
返回itype.GetProperty(propertyName).GetValue(实例,null);
}
公共IEnumerable GetClientValidationRules(ModelMetadata元数据、ControllerContext上下文)
{
ModelClientValidationRule vr=新的ModelClientValidationRule()
{
ErrorMessage=ErrorMessage,
ValidationType=“admissiondaycase”
};
添加(新的KeyValuePair(“admissiondateid”,admissiondateid));
vr.ValidationParameters.Add(新的KeyValuePair(“dischargedateid”,dischargedateid));
添加(新的KeyValuePair(“daycaseid”,daycaseid));
收益率;
}
编辑/更新

视图看起来是这样的-

<tr>
    <td>
        @Html.LabelFor(x => x.AdmissionTypeID)
    </td>
    <td>
        @Html.CustomDropDownListFor(a => a.AdmissionTypeID, Lookup.AdmissionTypes,Default.Constant.DROPDOWN)
        @Html.ValidationMessageFor(a=>a.AdmissionTypeID)
    </td>
</tr>

@LabelFor(x=>x.AdmissionTypeID)
@CustomDropDownListFor(a=>a.AdmissionTypeID,Lookup.AdmissionTypes,Default.Constant.DROPDOWN)
@Html.ValidationMessageFor(a=>a.AdmissionTypeID)
没有javascript或任何与此交互的东西,它非常基本,但有一些额外的细节-
此视图代码位于视图模板中,该模板在局部视图中使用

首先检查模型中的属性是否正确定义了
AdmissionDayCaseAttribute

然后,不返回
validationContext.MemberName
return
validationContext.DisplayName
。如果通过
DsiplayAttribute
修改成员名称,则可以执行以下操作:

  var memberName = validationContext.ObjectType.GetProperties()
    .Where(p => p.GetCustomAttributes(false)
    .OfType<DisplayAttribute>()
    .Any(a => a.Name == validationContext.DisplayName))
    .Select(p => p.Name).FirstOrDefault(); 

    return new ValidationResult(ErrorMessage, new List<String>() { memberName  });
var memberName=validationContext.ObjectType.GetProperties()
.Where(p=>p.GetCustomAttributes(false)
第()类
.Any(a=>a.Name==validationContext.DisplayName))
.Select(p=>p.Name).FirstOrDefault();
返回新的ValidationResult(ErrorMessage,new List(){memberName});

您也可以发布视图吗?是否包含@Html.ValidationMessageFor(model=>model.PropertyName)除了您的文本框之外?添加了视图,它在视图中肯定有validtionmessagefor-但是服务器端的memberName没有显示出来。我可以理解为什么我要使用IValidatableObject,但是我希望它对特定属性有效,而不是模型本身。尽管上述方法很有用,但并不能解决我无法获得validationContext中的memberName validationContext.DisplayName是否为空?否DisplayName不为空,但它与属性名称也不相同(因为我也在属性上声明了一个display属性)这确实有效,但可能性很小,如果有两个属性具有相同的显示名称,则不会有效-我只是想与您共享,谢谢:)