可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
We have an application with three layers: UI, Business, and Data. The data layer houses Entity Framework v4 and auto-generates our entity objects. I have created a buddy class for the entity VendorInfo
:
namespace Company.DataAccess { [MetadataType(typeof(VendorInfoMetadata))] public partial class VendorInfo { } public class VendorInfoMetadata { [Required] public string Title; [Required] public string Link; [Required] public string LinkText; [Required] public string Description; } }
I want this validation to bubble up to the UI, including custom validation messages assigned to them. In MVC this is a piece of cake but in web forms I have no clue where to begin. What is the best way to utilize model validation in asp.net web forms?
I did find an article that explains how to build a server control for it, but I can't seem to get it working. It compiles and even recognizes the control but I can never get it to fire.
Any ideas?
Thanks everyone.
回答1:
I solved it. It would appear that the server control I found was not designed to read fields in a buddy class via the MetadataType attribute. I modified the code to look for its validation attributes in the buddy class rather than the entity class itself.
Here is the modified version of the linked server control:
[DefaultProperty("Text")] [ToolboxData("<{0}:DataAnnotationValidator runat=server></{0}:DataAnnotationValidator>")] public class DataAnnotationValidator : BaseValidator { #region Properties /// <summary> /// The type of the source to check /// </summary> public string SourceTypeName { get; set; } /// <summary> /// The property that is annotated /// </summary> public string PropertyName { get; set; } #endregion #region Methods protected override bool EvaluateIsValid() { // get the type that we are going to validate Type source = GetValidatedType(); // get the property to validate FieldInfo property = GetValidatedProperty(source); // get the control validation value string value = GetControlValidationValue(ControlToValidate); foreach (var attribute in property.GetCustomAttributes( typeof(ValidationAttribute), true) .OfType<ValidationAttribute>()) { if (!attribute.IsValid(value)) { ErrorMessage = attribute.ErrorMessage; return false; } } return true; } private Type GetValidatedType() { if (string.IsNullOrEmpty(SourceTypeName)) { throw new InvalidOperationException( "Null SourceTypeName can't be validated"); } Type validatedType = Type.GetType(SourceTypeName); if (validatedType == null) { throw new InvalidOperationException( string.Format("{0}:{1}", "Invalid SourceTypeName", SourceTypeName)); } IEnumerable<MetadataTypeAttribute> mt = validatedType.GetCustomAttributes(typeof(MetadataTypeAttribute), false).OfType<MetadataTypeAttribute>(); if (mt.Count() > 0) { validatedType = mt.First().MetadataClassType; } return validatedType; } private FieldInfo GetValidatedProperty(Type source) { FieldInfo field = source.GetField(PropertyName); if (field == null) { throw new InvalidOperationException( string.Format("{0}:{1}", "Validated Property Does Not Exists", PropertyName)); } return field; } #endregion }
This code only looks in the buddy class. If you want it to check an actual class and then its buddy class, you'll have to modify it accordingly. I did not bother doing that because usually if you are using a buddy class for validation attributes it's because you are not able to use the attributes in the main entity class (e.g. Entity Framework).
回答2:
For model validation in web forms I'm using DAValidation library. It supports validation on client side (including unobtrusive validation), extensibility based on same principles as in MVC. It is MS-PL licensed and available via Nuget.
And here is bit out of date article describing with what thoughts control was build.