[英]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. 我正在建立一个ASP.NET MVC网站,我想在其中装饰带有验证属性的ViewModel。 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. 为此,我已经创建了一个自定义的
ValidationAttribute
并将其应用于我的StreetAddress
属性。
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. 这一切都很好,除了我实际上在进行两个地理编码请求-一个在ViewModel中进行验证,另一个在我的Controller中将纬度和经度输入到数据库中。 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. 为了完成这样的事情,我认为我应该在ViewModel中创建一个Latitude和Longitude属性。 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.
View本身不会涉及这2个属性,但是validate属性将报告地理编码失败并返回View或将结果写入属性。
For a validation attribute to access 3 properties, it has to be applied to the whole class. 为了使验证属性访问3个属性,必须将其应用于整个类。
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.
不过,我仍然没有弄清楚如何写属性。
How do I create a
ValidationAttribute
that can be applied to a whole class?
如何创建可应用于整个类的
ValidationAttribute
?
Below, I have posted the code that I want to transfrom into an attribute that can be applied to my ViewModel:
在下面,我已经发布了要转换为可以应用于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
. 当我将此属性应用于ViewModel时,我希望它将成功的地理编码结果写入两个属性并
return true
。 How can I implement that? 我该如何实施?
UPDATE #2: I think I just figured out how to write to a property. 更新#2:我想我只是想出了如何写属性。 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]
. 我的ViewModel中还有其他用内置ValidationAttributes装饰的属性,例如
[Required]
和[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?
将我的新属性应用于整个ViewModel类会完全破坏客户端验证,还是会在客户端上执行其他属性的验证,然后在服务器上执行总验证?
1) You can't access the outer class via a property level ValidationAttribute. 1)您不能通过属性级别的ValidationAttribute访问外部类。
You could use a custom model binder to accomplish this. 您可以使用自定义模型活页夹来完成此操作。 Simply detect the attributes and validate accordingly.
只需检测属性并进行相应验证。
Creating a custom model binder: http://www.singingeels.com/Articles/Model_Binders_in_ASPNET_MVC.aspx 创建自定义模型活页夹: http : //www.singingeels.com/Articles/Model_Binders_in_ASPNET_MVC.aspx
2) No. Did you try? 2)不,您尝试过吗?
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, that may do what you need.
它可能包含一项单独的技术,即类级别验证,可以满足您的需要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.