开发者

Validating Multiple Attributes

I am building an online store for local artists, and one of the requirements is to add an image to be associated with a given product. For the image, there are multiple elements that need to be validated; specifically dimensions, file size, and type.

Currently, I have the following set up to validate the image:

[LocalizedDisplayName(typeof(StoreManagementRes), "Image")]
[ImageSize(typeof(BesLogicSharedRes),"ValidationImageFileSizeMustBeLessThan20kb")]
[ImageDimension(typeof(BesLogicSharedRes), "ValidationImageDimensionMustBeLessThan640x480")]
[ImageType(typeof(BesLogicSharedRes), "ValidationImageTypeMustBeJpgOrPng")]
public int ImageFileId { get; set; }

The file that is uploaded does get validated properly, however, they are not necessarily called in the same order every time the application runs. In the end, if validation fails on more than one attribute, only one error message gets displayed. Again, not necessarily the first failed validation, nor the last. I would like to display all the errors at once so as not to frustrate the user.

If this is relevant, all 开发者_如何学Gothree image validation classes are sub classed from ValidationAttribute.


One thing to be thankful of is that the model keeps all errors rather than one of them, it's just the HtmlHelper that's displaying the first.

ValidationSummary should in fact display all errors on your model though I suspect you want the equivalent for an individual property.

Unfortunately a couple of the useful methods are private rather than protected so they had to be copy and pasted out of ValidationExtensions.cs. I did this with a slightly cut down version (no use of resource files for error messages, easy enough to do by getting the original version of GetUserErrorMessageOrDefault but you'll also have to check to take the related methods and fields from the class too). I also only did one function call but it's easy enough to impliment the overloads if needed.

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";
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜