Bla*_*ise 5 c# asp.net asp.net-mvc model-binding data-annotations
我的视图模型中有一些属性在保存时是可选的,但在提交时是必需的.总之,我们允许部分保存,但提交整个表单,我们确实希望确保所有必填字段都有值.
我现在能想到的唯一方法是:
视图模型具有所有[Required]属性.如果请求是部分保存,则在进入控制器操作时ModelState.IsValid变为false.然后我运行所有ModelState(这是一个ICollection<KeyValuePair<string, ModelState>>)错误并删除[Required]属性引发的所有错误.
但是如果请求是提交整个表单,我不会干涉ModelState和[Required]属性生效.
这个更难看.一个视图模型将包含[Required]操作方法用于提交的所有属性.但是对于部分保存,我将表单数据发布到使用相同视图模型而没有所有[Required]属性的不同操作.
显然,我最终会遇到很多重复的代码/视图模型.
我一直在考虑是否可以[SubmitRequired]为这些必需的属性创建自定义数据注释属性.并且以某种方式使得验证在部分保存时忽略它,但在提交时则忽略.
仍然没有一个明确的线索.有人可以帮忙吗?谢谢.
我的做法是添加条件检查注解属性,这个属性是从傻瓜学来的。
成为SaveMode视图模型的一部分。
SaveMode将属性标记为可为空,以便当不是时,其值是可选的Finalize。
但添加一个自定义注释属性[FinalizeRequired]:
[FinalizeRequired]
public int? SomeProperty { get; set; }
[FinalizeRequiredCollection]
public List<Item> Items { get; set; }
Run Code Online (Sandbox Code Playgroud)
这是属性的代码:
[AttributeUsage(AttributeTargets.Property)]
public abstract class FinalizeValidationAttribute : ValidationAttribute
{
public const string DependentProperty = "SaveMode";
protected abstract bool IsNotNull(object value);
protected static SaveModeEnum GetSaveMode(ValidationContext validationContext)
{
var saveModeProperty = validationContext.ObjectType.GetProperty(DependentProperty);
if (saveModeProperty == null) return SaveModeEnum.Save;
return (SaveModeEnum) saveModeProperty.GetValue(validationContext.ObjectInstance);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var saveMode = GetSaveMode(validationContext);
if (saveMode != SaveModeEnum.SaveFinalize) return ValidationResult.Success;
return (IsNotNull(value))
? ValidationResult.Success
: new ValidationResult(string.Format("{0} is required when finalizing", validationContext.DisplayName));
}
}
Run Code Online (Sandbox Code Playgroud)
对于原始数据类型,请检查value!=null:
[AttributeUsage(AttributeTargets.Property)]
public class FinalizeRequiredAttribute : FinalizeValidationAttribute
{
protected override bool IsNotNull(object value)
{
return value != null;
}
}
Run Code Online (Sandbox Code Playgroud)
对于IEnumerable收藏来说,
[AttributeUsage(AttributeTargets.Property)]
public class FinalizeRequiredCollectionAttribute : FinalizeValidationAttribute
{
protected override bool IsNotNull(object value)
{
var enumerable = value as IEnumerable;
return (enumerable != null && enumerable.GetEnumerator().MoveNext());
}
}
Run Code Online (Sandbox Code Playgroud)
这种方法通过从控制器中删除验证逻辑来最好地实现关注点分离。数据注释属性应该处理此类工作,哪个控制器只需要检查!ModelState.IsValid. ModelState这在我的应用程序中特别有用,因为如果每个控制器中的检查不同,我将无法重构为基本控制器。
| 归档时间: |
|
| 查看次数: |
4260 次 |
| 最近记录: |