我有一個DateTime TemplateEditor,我想向它添加正則表達式驗證。我有一個RegularExpression屬性可以用來裝飾模型,但是我不想用正則表達式來裝飾我所有模型中的每個日期時間屬性。如何在MVC3的TemplateEditor中將驗證屬性添加到模型屬性中
有沒有辦法讓我的自定義TemplateEditor添加適當的unobstrusive標籤時,它呈現文本框?
我有一個DateTime TemplateEditor,我想向它添加正則表達式驗證。我有一個RegularExpression屬性可以用來裝飾模型,但是我不想用正則表達式來裝飾我所有模型中的每個日期時間屬性。如何在MVC3的TemplateEditor中將驗證屬性添加到模型屬性中
有沒有辦法讓我的自定義TemplateEditor添加適當的unobstrusive標籤時,它呈現文本框?
您應該使用自定義ModelMetadataValidatorProvider
插入驗證程序,而不是在模板中添加驗證程序。首先,創建您的ModelMetadataProvider類:
public class MyModelMetadataValidatorProvider : DataAnnotationsModelValidatorProvider
{
internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory = Create;
internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>() {
{
typeof(RegularExpressionAttribute),
(metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)
}
};
internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
{
return new DataAnnotationsModelValidator(metadata, context, attribute);
}
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
List<ModelValidator> vals = base.GetValidators(metadata, context, attributes).ToList();
// inject our new validator
if (metadata.ModelType.Name == "DateTime")
{
DataAnnotationsModelValidationFactory factory;
RegularExpressionAttribute regex = new RegularExpressionAttribute(
"^(((0?[1-9]|1[012])/(0?[1-9]|1\\d|2[0-8])|(0?[13456789]|1[012])/(29|30)|(0?[13578]|1[02])/31)/(19|[2-9]\\d)\\d{2}|0?2/29/((19|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|(([2468][048]|[3579][26])00)))$");
regex.ErrorMessage = "Invalid date format";
if (!AttributeFactories.TryGetValue(regex.GetType(), out factory))
factory = DefaultAttributeFactory;
vals.Add(factory(metadata, context, regex));
}
return vals.AsEnumerable();
}
}
接下來,註冊您的ModelMetadataValidatorProvider在Global.asax.cs
在Application_Start
。
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new MyModelMetadataValidatorProvider());
現在,當你訪問一個模型,RegularExpressionAttribte將被連接到每個DateTime字段。您也可以擴展它以提供本地化的DateTime正則表達式和消息。
counsellorben
這只是闡述(和固定幾個小問題)上Consellorben的回答
public class ExtendedDataAnnotationsModelValidatorProvider : DataAnnotationsModelValidatorProvider
{
internal static DataAnnotationsModelValidationFactory DefaultAttributeFactory = Create;
internal static Dictionary<Type, DataAnnotationsModelValidationFactory> AttributeFactories = new Dictionary<Type, DataAnnotationsModelValidationFactory>()
{
{
typeof(RegularExpressionAttribute),
(metadata, context, attribute) => new RegularExpressionAttributeAdapter(metadata, context, (RegularExpressionAttribute)attribute)
}
};
internal static ModelValidator Create(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
{
return new DataAnnotationsModelValidator(metadata, context, attribute);
}
protected override IEnumerable<ModelValidator> GetValidators(ModelMetadata metadata, ControllerContext context, IEnumerable<Attribute> attributes)
{
if(!attributes.Any(i => i is RegularExpressionAttribute))
{
if (typeof(DateTime).Equals(metadata.ModelType) || (metadata.ModelType.IsGenericType && typeof(DateTime).Equals(metadata.ModelType.GetGenericArguments()[0])))
{
DataAnnotationsModelValidationFactory factory;
RegularExpressionAttribute regex = null;
switch (metadata.DataTypeName)
{
case "Date":
regex = new RegularExpressionAttribute(RegExPatterns.Date) { ErrorMessage = "Invalid date. Please use a m/d/yyyy format" };
break;
case "Time":
regex = new RegularExpressionAttribute(RegExPatterns.Time) { ErrorMessage = "Invalid time. Please use a h:mm format" };
break;
default: //DateTime
regex = new RegularExpressionAttribute(RegExPatterns.DateAndTime) { ErrorMessage = "Invalid date/time. Please use a m/d/yyyy h:mm format" };
break;
}
if (!AttributeFactories.TryGetValue(regex.GetType(), out factory))
factory = DefaultAttributeFactory;
yield return factory(metadata, context, regex);
}
}
}
}
,然後註冊它在Global.asax像這樣:
ModelValidatorProviders.Providers.Add(new ExtendedDataAnnotationsModelValidatorProvider());
我喜歡這些修訂版本,我將其保存以供將來使用。我的代碼是一個注入器類,我不需要擔心與預先存在的屬性可能發生衝突,因爲所有屬性都是在注入器類中創建的。另外,爲什麼要運行標準DataAnnotationsModelValidator提供程序和您的自定義提供程序? – counsellorben
那是kickass。謝謝。 –