我正在为本地艺术家建立一个在线商店,其中一个要求是添加一个与给定产品相关联的图像。对于图像,有多个元素需要验证;特别是尺寸,文件大小和类型。
目前,我有以下设置来验证图像:
[LocalizedDisplayName(typeof(StoreManagementRes), "Image")]
[ImageSize(typeof(BesLogicSharedRes),"ValidationImageFileSizeMustBeLessThan20kb")]
[ImageDimension(typeof(BesLogicSharedRes), "ValidationImageDimensionMustBeLessThan640x480")]
[ImageType(typeof(BesLogicSharedRes), "ValidationImageTypeMustBeJpgOrPng")]
public int ImageFileId { get; set; }
上传的文件确实得到了正确验证,但是,每次运行应用程序时,它们不一定以相同的顺序调用。最后,如果验证在多个属性上失败,则只显示一条错误消息。同样,不一定是第一次失败的验证,也不一定是最后一次。我想一次显示所有错误,以免挫败用户。
如果这是相关的,则所有三个图像验证类都归入ValidationAttribute
。
答案 0 :(得分:1)
值得庆幸的是,模型会保留所有错误而不是其中一个错误,只是显示第一个错误的HtmlHelper。
ValidationSummary实际上应该显示模型上的所有错误,但我怀疑你想要一个单独属性的等价物。
不幸的是,一些有用的方法是私有的而不是受保护的,所以它们必须从ValidationExtensions.cs
复制并粘贴。我用一个略微减少的版本做了这个(没有使用资源文件的错误消息,通过获取原始版本的GetUserErrorMessageOrDefault很容易,但你也必须检查从类中获取相关的方法和字段) 。我也只做过一次函数调用,但如果需要,它很容易实现重载。
public static MvcHtmlString ValidationSummaryForSubModel(this HtmlHelper html, bool excludePropertyErrors, string message, IDictionary<string, object> htmlAttributes)
{
string prefix = html.ViewData.TemplateInfo.HtmlFieldPrefix;
var props = html.ViewData.ModelState.Where(x => x.Key.StartsWith(prefix));
var errorprops = props.Where(x => x.Value.Errors.Any()).SelectMany(x=>x.Value.Errors);
if (html == null) {
throw new ArgumentNullException("html");
}
FormContext formContext = (html.ViewContext.ClientValidationEnabled) ? html.ViewContext.FormContext : null;
if (formContext == null && html.ValidForSubModel())
{
return null;
}
string messageSpan;
if (!String.IsNullOrEmpty(message)) {
TagBuilder spanTag = new TagBuilder("span");
spanTag.SetInnerText(message);
messageSpan = spanTag.ToString(TagRenderMode.Normal) + Environment.NewLine;
}
else {
messageSpan = null;
}
StringBuilder htmlSummary = new StringBuilder();
TagBuilder unorderedList = new TagBuilder("ul");
foreach (ModelError modelError in errorprops) {
string errorText = GetUserErrorMessageOrDefault(html.ViewContext.HttpContext, modelError, null /* modelState */);
if (!String.IsNullOrEmpty(errorText)) {
TagBuilder listItem = new TagBuilder("li");
listItem.SetInnerText(errorText);
htmlSummary.AppendLine(listItem.ToString(TagRenderMode.Normal));
}
}
if (htmlSummary.Length == 0) {
htmlSummary.AppendLine(_hiddenListItem);
}
unorderedList.InnerHtml = htmlSummary.ToString();
TagBuilder divBuilder = new TagBuilder("div");
divBuilder.MergeAttributes(htmlAttributes);
divBuilder.AddCssClass((html.ViewData.ModelState.IsValid) ? HtmlHelper.ValidationSummaryValidCssClassName : HtmlHelper.ValidationSummaryCssClassName);
divBuilder.InnerHtml = messageSpan + unorderedList.ToString(TagRenderMode.Normal);
if (formContext != null) {
// client val summaries need an ID
divBuilder.GenerateId("validationSummary");
formContext.ValidationSummaryId = divBuilder.Attributes["id"];
formContext.ReplaceValidationSummary = !excludePropertyErrors;
}
return MvcHtmlString.Create(divBuilder.ToString(TagRenderMode.Normal));
}
private static string GetUserErrorMessageOrDefault(HttpContextBase httpContext, ModelError error, ModelState modelState)
{
if (!String.IsNullOrEmpty(error.ErrorMessage))
{
return error.ErrorMessage;
}
if (modelState == null)
{
return null;
}
string attemptedValue = (modelState.Value != null) ? modelState.Value.AttemptedValue : null;
//return String.Format(CultureInfo.CurrentCulture, GetInvalidPropertyValueResource(httpContext), attemptedValue);
return "Error";
}