Implementing a class-level validation attribute that writes to a property inside the class


Implementing a class-level validation attribute that writes to a property inside the class



I'm building an ASP.NET MVC site where I want to decorate my ViewModels with validation attributes. One of the things I want to validate is that the address that a user submits through a form is geocodable. For that, I have already created a custom ValidationAttribute and have applied to my StreetAddress property.

This is all good, except that I am actually making two geocoding requests - one in my ViewModel for validation and another in my Controller to input the latitude and longitude into my database. I want to cut down on unnecessary network usage and delays, so I need to pass the result from the validation geocode into my controller.

To accomplish such a thing, I think I should create a Latitude and Longitude property in my ViewModel. The View itself won't touch these 2 properties, but the validation attribute will either report a failure in geocoding and return the View or write the results into the properties.

For a validation attribute to access 3 properties, it has to be applied to the whole class. I don't know how to do that yet, but that's what this question is for.

UPDATE: Thanks to this answer, I have figured out how to create a class-level validation attribute. The link in the answer also demonstrates how to read the contents of a property inside the class (via Reflection). I still haven't figured out how to write to a property, though.


My Questions

How do I create a ValidationAttribute that can be applied to a whole class? Below, I have posted the code that I want to transfrom into an attribute that can be applied to my ViewModel:

public class GeocodableAttribute : ValidationAttribute     {         public GeocodableAttribute() : base()         {             ErrorMessage = "We weren't able to find that location.";         }         public override bool IsValid(object value)         {             if (value == null) //we don't care if it's required or not.             {                 return true;             }             var address = (string)value;             var response = Geocoder.CallGeoWS(address.Trim());             if(response.Status=="ZERO_RESULTS")             {                 return false;             }             return true;         }     } 


How do I have the attribute write to certain properties in the class that it is applied to? When I apply this attribute to my ViewModel, I want it to write successful geocoding results into two properties and return true. How can I implement that?

UPDATE #2: I think I just figured out how to write to a property. Should the following code work?

    private static void WritePropertyValue(object obj, string propertyName, object valueToWrite)     {         if (obj == null) return null;         var type = obj.GetType();         var propertyInfo = type.GetProperty(propertyName);         if (propertyInfo == null) return null;         propertyInfo.SetValue(obj, valueToWrite, null);     } 

Will this break client-side validation for other attributes/properties? I have other properties in my ViewModel that I have decorated with built-in ValidationAttributes, such as [Required] and [Range]. I have also enabled client-side validation for them. Will applying my new attribute to the whole ViewModel class completely break client-side validation or will validation for the other properties be performed on the client and then total validation will be performed on the server?


Jquery problem:validation code not working

1:

How to make selectedItem in a SelectList be dynamic
1) You can't access the outer class via a property level ValidationAttrialthough e. Master ASP.NET MVC . How do I convert DateTime format to ShortDateString in Jquery? You could use a custom model binder to accomplish this. Why is VS2010 in ASP.NET MVC2 giving me the wrong JQuery intellisense? Simply detect the attrialthough es and validate accordingly. Unit testing with EF4 “Code First” and Repository. Passing nested arrays to asp.net mvc using jQuery's $.ajax Creating a custom model binder: http://www.singingeels.com/Articles/Model_Binders_in_ASPNET_MVC.aspx. How to fake Http post? 2) No. Did you try?. This is almost a duplicate. I'd check out the question and answers for my dupe submission. It may contain a separate technique, class level validation, this may did what you need..


48 out of 100 based on 18 user ratings 178 reviews

#