2012-02-21 77 views
5

我在每個地方都找到了一半的解決方案,但我無法得到真正的答案。MVC3 ValidationAttribute validationContext.memberName爲null

我已經創建了一個從ValidationAttribute和IClientValidatable繼承的驗證屬性。

一切似乎工作正常,如果我把一個驗證總結頁面上的錯誤顯示。

但是,我無法得到與該屬性相關的文本框旁邊顯示的錯誤。

我認爲這是因爲我需要將屬性名稱添加到驗證結果。

然而,這是失敗的地方,因爲我無法從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; 
    } 

編輯/ UPDATE

的觀點是這樣的 -

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

有沒有JavaScript或任何與此互動,其基本相當,但有些額外的細節 - 這個視圖代碼在視圖模板中,在局部視圖中使用

+0

您是否也可以發佈您的視圖?除了文本框之外,您是否包含了@ Html.ValidationMessageFor(model => model.PropertyName)? – CjCoax 2012-02-21 04:48:25

+0

已添加視圖,它肯定有validtionmessagefor在視圖中 - 但服務器端的memberName不顯示 – 2012-02-21 04:57:58

回答

7

首先檢查AdmissionDayCaseAttribute在模型中的屬性上正確定義。

然後而不是返回validationContext.MemberName返回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 }); 
+0

我可以理解爲什麼我會使用IValidatableObject,但我希望它有效的特定屬性,而不是模型本身。 雖然上面雖然有用,但不修復我的delima未從validationContext獲取memberName – 2012-02-21 11:05:40

+0

validationContext.DisplayName是否爲空? – 2012-02-21 11:07:47

+0

沒有顯示名稱不是空的,但它與屬性名稱不一樣(因爲我已經在屬性上聲明瞭顯示屬性) – 2012-02-21 11:22:16

相關問題