- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
作为 ASP.NET Core MVC 1.0 项目的一部分,我有一个带有 ICollection<>
的 ViewModel属性(property)。我需要验证此集合是否包含一项或多项。我的自定义验证属性未执行。
在我的实例中,它包含来自 multipart/form-data
的多个文件附件形式。
我用自定义验证属性装饰了 ViewModel 中的属性:
[RequiredCollection]
public ICollection<IFormFile> Attachments { get; set; }
下面是自定义属性类。它只是检查集合不为空且元素大于零:
public class RequiredCollectionAttribute : ValidationAttribute
{
protected const string DefaultErrorMessageFormatString = "You must provide at least one.";
public RequiredCollectionAttribute() : base(DefaultErrorMessageFormatString) { }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var collection = (ICollection) value;
return collection == null || collection.Count > 0
? ValidationResult.Success
: new ValidationResult(ErrorMessageString);
}
}
最后,在 Controller 中,我确保 POST
中的 ViewModel请求有效,应该触发验证:
[HttpPost]
public async Task<IActionResult> Method(MethodViewModel viewModel)
{
if (!ModelState.IsValid)
return View(viewModel);
...
}
如果我在 ModelState.IsValid
处中断来电,内容ModelState.Values
对于 Attachments
属性是:
RequiredCollectionAttribute.IsValid()
内方法曾经被击中过吗?ValidationState
设置为 Skipped
对于 Attachments
属性(property)?--
MethodViewModel 定义,按要求:
public class MethodViewModel
{
...
[Display(Name = "Attachments")]
[RequiredCollection(ErrorMessage = "You must attached at least one file.")]
public ICollection<IFormFile> Attachments { get; set; }
...
}
--
下面是 actionContext.ModelState
的修剪值(以 JSON 格式导出),按要求提供。这是在进入全局操作过滤器时遇到断点时的状态,OnActionExecuting()
:
{
"Count": 19,
"ErrorCount": 0,
"HasReachedMaxErrors": false,
"IsReadOnly": false,
"IsValid": true,
"Keys":
[
"Attachments"
],
"MaxAllowedErrors": 200,
"ValidationState": Valid,
"Values":
[
{
"AttemptedValue": null,
{
},
"RawValue": null,
"ValidationState": Microsoft.AspNet.Mvc.ModelBinding.ModelValidationState.Skipped
}
],
{
[
"Key": "Attachments",
{
"AttemptedValue": null,
"RawValue": null,
"ValidationState": Microsoft.AspNet.Mvc.ModelBinding.ModelValidationState.Skipped
},
"key": "Attachments",
{
"AttemptedValue": null,
"RawValue": null,
"ValidationState": Microsoft.AspNet.Mvc.ModelBinding.ModelValidationState.Skipped
}
]
}
}
--
用于呈现 Attachments
的 View 的 Razor 语法输入字段。
<form role="form" asp-controller="Controller" asp-action="Method" method="post" enctype="multipart/form-data">
...
<div class="form-group">
<label asp-for="Attachments" class="control-label col-xs-3 col-sm-2"></label>
<div class="col-xs-9 col-sm-10">
<input asp-for="Attachments" class="form-control" multiple required>
<span asp-validation-for="Attachments" class="text-danger"></span>
</div>
</div>
...
</form>
最佳答案
如果发现 IFormFile
或 IFormFile
的集合不为 null,那么 MVC 似乎正在抑制进一步验证。
如果您查看 FormFileModelBinder.cs
代码,you can see the issue right here .如果 Binder 能够从上面的 if/elseif/else 子句中获得非空结果,它将抑制验证。
在一次测试中,我用这样的代码制作了一个 View 模型:
[ThisAttriuteAlwaysReturnsAValidationError]
public IFormFile Attachment { get;set; }
当我实际上传一个文件到这个例子时,它上面的 always-erroring 属性永远不会被调用。
因为这是来自 MVC 本身,我认为你最好的选择是实现 IValidateableObject
接口(interface)。
public class YourViewModel : IValidatableObject
{
public ICollection<IFormFile> Attachments { get;set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
var numAttachments = Attachments?.Count() ?? 0;
if (numAttachments == 0)
{
yield return new ValidationResult(
"You must attached at least one file.",
new string[] { nameof(Attachments) });
}
}
}
此方法仍将被调用,因为它不与任何单独的属性相关联,因此不会像您的属性那样被 MVC 抑制。
如果您必须在多个地方执行此操作,您可以创建一个扩展方法来提供帮助。
public static bool IsNullOrEmpty<T>(this IEnumerable<T> collection) =>
collection == null || !collection.GetEnumerator().MoveNext();
这是filed as a bug并且应该在 1.0.0 RTM 中修复。
关于c# - MVC ICollection<IFormFile> ValidationState 始终设置为 Skipped,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35989885/
作为 ASP.NET Core MVC 1.0 项目的一部分,我有一个带有 ICollection<> 的 ViewModel属性(property)。我需要验证此集合是否包含一项或多项。我的自定义验
我是一名优秀的程序员,十分优秀!