2012-02-21 2 views
5

어디서나 반 솔루션을 찾았지만 이에 대한 실제 답변을 얻을 수 없습니다.MVC3 ValidationAttribute validationContext.memberName is 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; 
    } 

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

아니, 자바 스크립트 또는이와 상호 작용 무엇이든 그것의 아주 기본적인 그러나 몇 가지 추가 세부 사항 - 이보기 코드 부분보기에서 사용되는 뷰 템플릿에 있음

+0

보기를 게시 할 수 있습니까? 텍스트 상자 외에 @ Html.ValidationMessageFor (model => model.PropertyName)를 포함 시켰습니까? – CjCoax

+0

보기를 추가했습니다.보기에 validtionmessagefor가 있습니다. 서버 쪽에서 memberName이 표시되지 않습니다. –

답변

7

먼저모델의 속성에서이 올바르게 정의됩니다.

그런 다음 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을 가져 오지 못하도록 수정하지 않았습니다 –

+0

validationContext.DisplayName이 비어 있습니까? –

+0

표시 이름은 비어 있지 않습니다. 그러나 속성 이름과 동일하지 않습니다. (속성에 표시 속성도 선언했기 때문에) –