【发布时间】:2010-07-05 23:48:12
【问题描述】:
我正在构建一个 ASP.NET MVC 站点,我想在其中使用验证属性来装饰我的 ViewModel。我要验证的一件事是用户通过表单提交的地址是可地理编码的。为此,我已经创建了一个自定义 ValidationAttribute 并应用于我的 StreetAddress 属性。
这一切都很好,除了我实际上提出了两个地理编码请求 - 一个在我的 ViewModel 中用于验证,另一个在我的控制器中用于将纬度和经度输入到我的数据库中。我想减少不必要的网络使用和延迟,所以我需要通过 验证地理编码的结果到我的控制器中。
要完成这样的事情,我认为我应该在我的 ViewModel 中创建一个纬度和经度属性。 View 本身不会触及这 2 个属性,但验证属性会报告地理编码失败并返回 View 或将结果写入属性。
对于访问 3 个属性的验证属性,它必须应用于整个类。 我还不知道该怎么做,但这就是这个问题的目的。
更新:感谢this answer,我已经弄清楚了如何创建类级验证属性。 link in the answer 还演示了如何读取类内属性的内容(通过反射)。不过,我还没有弄清楚如何写入属性。
我的问题
如何创建可以应用于整个班级的ValidationAttribute?下面,我发布了我想要转换为可应用于我的 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;
}
}
我如何将属性写入类中的某些属性?当我将此属性应用于我的 ViewModel 时,我希望它将成功的地理编码结果写入两个属性和return true。我该如何实现?
更新 #2: 我想我只是想出了如何写入属性。下面的代码应该工作吗?
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);
}
这会破坏其他属性/属性的客户端验证吗? 我的 ViewModel 中有其他属性,我用内置的 ValidationAttributes 进行了修饰,例如 [Required] 和 [Range]。我还为他们启用了客户端验证。将我的新属性应用到整个 ViewModel 类会完全破坏客户端验证,还是会在客户端执行对其他属性的验证,然后在服务器上执行全部验证?
【问题讨论】:
标签: c# asp.net-mvc validation asp.net-mvc-2 data-annotations