2012-02-21 13 views
5

Znajduję pół rozwiązania wszędzie, ale nie mogę uzyskać prawdziwej odpowiedzi na to.MVC3 ValidationAttribute validationContext.memberName ma wartość null

Utworzono atrybut sprawdzania poprawności dziedziczący z ValidationAttribute i IClientValidatable.

Wszystko wydaje się działać dobrze, a jeśli wstawię podsumowanie sprawdzania poprawności na stronie, wyświetlany jest błąd.

Jednak nie mogę wyświetlić błędu wyświetlanego obok pola tekstowego odnoszącego się do właściwości.

Myślę, że to dlatego, że muszę dodać nazwę właściwości do wyniku sprawdzania poprawności.

JEDNAK jest to miejsce, w którym się nie powiedzie, ponieważ nie mogę uzyskać nazwy elementu z validationContext.

Czy istnieje sposób, aby to umożliwić? Czy może czegoś brakuje?

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

widok wygląda następująco -

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

nie ma javascript lub cokolwiek interakcji z tym, jego dość podstawowe jednak kilka dodatkowych szczegółów - kod ten widok znajduje się w szablonie widoku, który jest używany w częściowym widoku

+0

Czy możesz również opublikować swój widok? Czy oprócz twoich pól tekstowych włączyłeś @ Html.ValidationMessageFor (model => model.PropertyName)? – CjCoax

+0

Dodałem widok, to zdecydowanie ma validtionmessagefor w widoku - jednak po stronie serwera memberName nie pokazuje się –

Odpowiedz

7

Najpierw sprawdź, czy AdmissionDayCaseAttribute jest poprawnie zdefiniowany we właściwości w modelu.

Wtedy zamiast wrócić validationContext.MemberName zwrot validationContext.DisplayName. Jeśli zmodyfikowałeś nazwę członka poprzez DsiplayAttribute, możesz zrobić coś takiego:

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

Mogę zrozumieć, dlaczego użyłbym IValidatableObject, jednak chcę, żeby to było ważne dla konkretnej właściwości, a nie sam model . Powyższe, chociaż użyteczne, nie naprawia mojej delimii nieotrzymania elementu memberName z validationContext –

+0

Czy właściwość validationContext.DisplayName jest pusta? –

+0

Żadna nazwa wyświetlana nie jest pusta, ale nie jest to ta sama nazwa co właściwość (ponieważ zadeklarowałem również atrybut wyświetlania w tej właściwości) –

Powiązane problemy