我正在为我的MVC和SIlverlight使用元数据验证。然而,silverlight的类不起作用,我认为它是由于Silverlight 4不存在的MetadataTypeAttribute。这似乎是我的项目的这一部分唯一的东西...我试图避免做的事情自定义,因为我不想重新发明轮子,但验证类似乎没有呈现预期的结果..:
以下是我的CLR解决方案:
var metadataAttrib = this.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();
var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : this.GetType();
var buddyClassProperties = TypeDescriptor.GetProperties(buddyClassOrModelClass).Cast<PropertyDescriptor>();
var modelClassProperties = TypeDescriptor.GetProperties(this.GetType()).Cast<PropertyDescriptor>();
var brokenRules = from buddyProp in buddyClassProperties
join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
from attribute in buddyProp.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(modelProp.GetValue(this))
select new BrokenRule() { FieldName = buddyProp.Name, ErrorMessage = attribute.FormatErrorMessage("") };
brokenRulesList = brokenRules.ToList();
...这是Silverlight的代码
var metadataAttrib = this.GetType().GetCustomAttributes(typeof(MetadataTypeAttribute), true).OfType<MetadataTypeAttribute>().FirstOrDefault();
var buddyClassOrModelClass = metadataAttrib != null ? metadataAttrib.MetadataClassType : this.GetType();
var buddyClassProperties = buddyClassOrModelClass.GetType().GetProperties();
var modelClassProperties = this.GetType().GetProperties();
var validationContext = new ValidationContext(this, null, null);
var validationResults = from buddyProp in buddyClassProperties
join modelProp in modelClassProperties on buddyProp.Name equals modelProp.Name
from attribute in buddyProp.GetCustomAttributes(true).OfType<ValidationAttribute>().Cast<ValidationAttribute>()
where buddyProp.Name == modelProp.Name
select attribute.GetValidationResult(modelProp, validationContext);
brokenRulesList = new List<BrokenRule>();
foreach (ValidationResult vr in validationResults)
{
foreach (string memberName in vr.MemberNames)
brokenRulesList.Add(new BrokenRule() { FieldName = memberName, ErrorMessage = vr.ErrorMessage });
}
...然而,Silverlight代码无法运行..以下是测试用例...
[MetadataType(typeof(UserMetadata))]
public partial class User
{
public partial class UserMetadata
{
[Required(ErrorMessageResourceName = "UserIDValidationMessage", ErrorMessageResourceType = typeof(AppResources))]
public System.Guid ID { get; set; }
public Nullable<int> UID { get; set; }
[Display(Name="UserUsernameLabel", Description="Username", ResourceType=typeof(AppResources))]
[Required(ErrorMessageResourceName = "UserUsernameValidationMessage", ErrorMessageResourceType = typeof(AppResources))]
[StringLength(70, ErrorMessageResourceName="UserUsernameValidationMessage", ErrorMessageResourceType = typeof(AppResources))]
public string Username { get; set; }
[Display(Name="UserFirstNameLabel", Description="First Name", ResourceType=typeof(AppResources))]
[StringLength(90, ErrorMessageResourceName="UserFirstNameValidationMessage", ErrorMessageResourceType = typeof(AppResources))]
public string FirstName { get; set; }
}
我为silverlight创建了一个类,它允许它编译,但它没有工作 - 正如预期的那样..
using System;
using System.Reflection;
namespace System.ComponentModel.DataAnnotations
{
public class MetadataTypeAttribute : Attribute
{
public MetadataTypeAttribute(Type t)
{
MetadataClassType = t;
}
public Type MetadataClassType
{
get;
set;
}
}
}
有谁知道如何简单地利用Silverlight的元数据类?为什么metadatatype属性不存在我不知道。有什么建议吗?
答案 0 :(得分:0)
如果要在Silverlight中使用验证属性,则必须执行以下三项操作之一:
使用工具包DataGrid显示数据 - 这会自动验证您的属性(我已经看到其他控件执行此操作,例如Telerik的RadGridView)
在属性设置器中手动验证,如果值无效,则抛出ValidationException。您还必须在Bindings中将ValidatesOnExceptions和NotifyOnValidationError设置为true。
Implement INotifyDataErrorInfo or IDataError,并通过这些接口中的方法设置验证错误。
选项3是推荐的方法,看起来最适合您的目的。
查看此链接了解更多信息msdn.microsoft.com/en-us/library/dd901590(v = vs.95).aspx
最后,INotifyDataErrorInfo界面可能有点令人生畏 - 在你可以使用它之前有很多管道可以解决。但是,Jeremy Likness的this post可能会有所帮助。 请注意,您不必像示例中那样在setter中进行验证。