2011-10-11 146 views
0

我建立了本地藝術家的在線商店,並要求之一是增加要與特定產品關聯的圖像。對於圖像,有多個元素需要驗證;特別是尺寸,文件大小和類型。驗證多發性屬性

目前,我有以下設置驗證圖像:

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

被上傳並得到驗證正確,但是,他們並不一定每次叫以相同的順序文件的應用程序運行。最後,如果驗證在多個屬性上失敗,則只顯示一條錯誤消息。再次,不一定是第一次失敗的驗證,也不是最後一次。我想一次顯示所有錯誤,以免挫傷用戶。

如果這是相關的,所有三個圖像驗證類子從ValidationAttribute歸類。

回答

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