问题
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.
来源:https://stackoverflow.com/questions/5600707/how-do-you-do-web-forms-model-validation