Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC3 ValidationAttribute validationContext.memberName is null

I find half solutions everywhere but I cannot get a real answer for this.

I have created a validation attribute inheriting from ValidationAttribute and IClientValidatable.

Everything seems to work fine, and if I put a validation summary on the page the error displays.

however I cannot get the error displaying beside the textbox relating to the property.

I think this is because I need to add the property name to the validation result.

HOWEVER this is where it fails, because I cannot get the member name from the validationContext.

is there a way to enable this to happen? Or am I missing something?

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

the view looks like this -

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

There no javascript or anything interacting with this, its pretty basic however some extra details - this view code is in a view template, which is used IN a partial view

like image 377
m.t.bennett Avatar asked Feb 21 '12 03:02

m.t.bennett


1 Answers

First check that the AdmissionDayCaseAttribute is correctly definied on the property in your model.

Then instead of returning validationContext.MemberName return validationContext.DisplayName. If you modified the member name through the DsiplayAttribute the you could do something like this :

  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  });
like image 129
Tomasz Jaskuλa Avatar answered Oct 12 '22 23:10

Tomasz Jaskuλa