2012-08-13 58 views
3

我有多個文件上傳ViewsViewModel如下結合:與數據註解視圖模型在ASP.NET MVC多文件上傳3

@model IVRControlPanel.Models.UploadNewsModel 
    @using (Html.BeginForm("index", "NewsUpload", FormMethod.Post, new { name = "form1", @id = "form1" })) 
     { 
      @Html.ValidationSummary(true) 

      <div class="field fullwidth"> 
       <label for="text-input-normal"> 
        @Html.Label("Select Active Date Time")</label> 
       <input type="text" id="active" value="@DateTime.Now" /> 
       @Html.ValidationMessageFor(model => model.ActiveDateTime) 
      </div> 

      <div class="field fullwidth"> 
       <label> 
        @Html.Label("Select Language") 
       </label> 
       @Html.DropDownList("Language", (SelectList)ViewBag.lang) 
      </div> 

      <div class="field"> 
       <label> 
        @Html.Label("General News") 
       </label> 
       @Html.TextBoxFor(model => model.generalnews, new { name = "files", @class="custom-file-input", type = "file" }) 
       @Html.ValidationMessageFor(model => model.generalnews) 
      </div> 
      <div class="field"> 
       <label> 
        @Html.Label("Sports News") 
       </label> 
       @Html.TextBoxFor(model => model.sportsnews, new { name = "files", @class = "custom-file-input", type = "file" }) 
       @Html.ValidationMessageFor(model => model.sportsnews) 
      </div>   
      <div class="field"> 
       <label> 
        @Html.Label("Business News") 
       </label> 
       @Html.TextBoxFor(model => model.businessnews, new { name = "files", @class = "custom-file-input", type = "file" }) 
       @Html.ValidationMessageFor(model => model.businessnews) 
      </div>    
      <div class="field"> 
       <label> 
        @Html.Label("International News") 
       </label> 
       @Html.TextBoxFor(model => model.internationalnews, new { name = "files", @class = "custom-file-input", type = "file" }) 
       @Html.ValidationMessageFor(model => model.internationalnews) 
      </div>  
      <div class="field"> 
       <label> 
        @Html.Label("Entertaintment News") 
       </label> 
       @Html.TextBoxFor(model => model.entertaintmentnews, new { name = "files", @class = "custom-file-input", type = "file" }) 
       @Html.ValidationMessageFor(model => model.entertaintmentnews) 
      </div>   

      <footer class="pane"> 
       <input type="submit" class="bt blue" value="Submit" /> 
      </footer>        
     } 

查看模型驗證文件上傳的允許擴展如下:

public class UploadNewsModel 
{ 
    public DateTime ActiveDateTime { get; set; } 

    // public IEnumerable<SelectListItem> Language { get; set; } 

    [File(AllowedFileExtensions = new string[] { ".jpg", ".gif", ".tiff", ".png", ".pdf", ".wav" }, MaxContentLength = 1024 * 1024 * 8, ErrorMessage = "Invalid File")] 
    public HttpPostedFileBase files { get; set; } 

} 

控制器:保存多個文件,如果錯誤是返回查看存在

[HttpPost] 
      public ActionResult Index(UploadNewsModel news, IEnumerable<HttpPostedFileBase> files) 
      { 
       if (ModelState.IsValid) 
       { 
        foreach (var file in files) 
        { 
         if (file != null && file.ContentLength > 0) 
         { 
          var fileName = Path.GetFileName(file.FileName); 
          var serverpath = Server.MapPath("~/App_Data/uploads/News"); 
          var path = Path.Combine(serverpath, fileName); 
          if (!Directory.Exists(serverpath)) 
          { 
           Directory.CreateDirectory(serverpath); 
          } 

          file.SaveAs(path); 
         } 

        } 
       } 
       return View(news); 
      } 

     } 

問題的解釋 如何定義爲這五個文件上傳輸入控制視圖模型,以便示出了用於相應的驗證錯誤對應的錯誤,如果上載的文件的文件擴展名是不允許的類型。我只有一個查看所有五個文件上傳控件的模型項目。

什麼可以是最好的方式來定義這些多文件上傳控制的視圖模型,以顯示相應的驗證錯誤,而不是用戶嘗試上傳不允許的擴展文件?

回答

2

這裏真正的問題是,MVC沒有一個體面的模型聯編程序的HTTP文件。

所以,除非你使用mvc futures這樣的項目,它有一些額外的文件上傳支持,你將不得不去弄些什麼骯髒的東西,並自己努力工作。

下面是一個可能對你有點幫助的例子。

首先,我將創建一個視圖模型來表示一個文件是這樣的:

public class FileViewModel 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
    public bool Delete { get; set; } 
    public string ExistingUrl { get; set; } 

    public HttpPostedFileBase FileBase { get; set; } 
} 

顯然性能取決於您的需求,最重要的一點是FileBase,它是它自己的模式。

下,(在你的情況UploadNewsModel)爲您的網頁視圖模型:

public class IndexViewModel 
{ 
    public IList<FileViewModel> Files { get; set; } 
} 

這裏最重要的一點是文件的IList的,這是我們如何捕捉多個文件(在當前的實現與'文件' 你只拍攝一個

到頁面上水平視圖:

@model IndexViewModel 
<form method="post" action="@Url.Action("Index")" enctype="multipart/form-data"> 
@Html.ValidationSummary(true) 
@Html.EditorFor(x => x.Files) 
<input type="submit" value="Submit" /> 
</form> 

注意EditorFor,我們下一步會做的就是創建一個EditorTemplateFileViewModel應該在這一點上使用。

像這樣:

@model FileViewModel 

<h4>@Model.Name</h4> 
@Html.HiddenFor(x => x.Id) 
@Html.CheckBoxFor(x => x.Delete) 

<input @("name=" + ViewData.TemplateInfo.HtmlFieldPrefix + ".FileBase") type="file" /> 

ViewData.TemplateInfo的使用。HtmlFieldPrefix,它有點爛,但就像我說的這是因爲對文件輸入類型的mvc支持不佳。我們必須自己做。我們除了每個文件的名稱都像'[0] .FileBase'等。

這將在POST操作中正確填充FileViewModel

到目前爲止好,驗證呢?

再次,您可以在服務器上手動執行此操作。測試自己的文件擴展名,並簡單地使用下面的錯誤添加到像模式:

ModelState.AddModelError("","Invalid extension.") 

在另一方面,擴展驗證應該在客戶端完成(和以及在服務器端)