2012-03-13 329 views
0

我希望網站的用戶同時上傳多個圖片,最多可以添加5個圖片。我創建了我的所有ViewModels以及[HttpPost]方法,這些方法將處理圖像列表並遍歷每個圖像,從而保存圖像。是否可以使用表單在MVC中提交列表?

我的問題是:如何在Post方法中接收該列表?

我已經爲我的ViewModels下面的代碼:

public class ImageCreateViewModel 
{ 
    public int ImageId { get; set; } 

    public int CollectionId { get; set; } 

    [Required(ErrorMessage = "Please enter a description of the photo.")] 
    [MaxLength(50)] 
    public string Description { get; set; } 

    [Required(ErrorMessage = "Please attach an image.")] 
    public HttpPostedFileBase Image { get; set; } 

    public string Location { get; set; } 

    public int Order { get; set; } 
} 

public class ImagesCreateViewModel : ImageCreateViewModel 
{ 
    public List<ImageCreateViewModel> Images { get; set; } 

    public MyEnumerator GetEnumerator() 
    { 
     return new MyEnumerator(this); 
    } 
} 


public class MyEnumerator 
{ 
    int index; 
    ImagesCreateViewModel imagesCreateViewModel; 

    public MyEnumerator(ImagesCreateViewModel imagesCreateViewModel) 
    { 
     this.imagesCreateViewModel = imagesCreateViewModel; 
     index = -1; 
    } 

    public bool MoveNext() 
    { 
     index++; 
     return (index < imagesCreateViewModel.Images.Count()); 
    } 

    public ImageCreateViewModel Current 
    { 
     get 
     { 
      return (imagesCreateViewModel.Images[index]); 
     } 
    } 
} 

這裏是我的控制器:

[HttpPost] 
public ActionResult CreateImages(ImagesCreateViewModel imagesEditViewModel) 
{ 
    if (!ModelState.IsValid) 
    { 
     return View(imagesEditViewModel); 
    } 

    foreach (ImageCreateViewModel imageCreateViewModel in imagesEditViewModel) 
    { 
     string fileName = Guid.NewGuid().ToString(); 
     string serverPath = Server.MapPath("~"); 
     string contentPath = String.Format("Content\\{0}\\Content\\Images\\{1}", Helper.Helper.ResolveBrand(), fileName); 
     string imagePath = serverPath + contentPath; 

     bool success = Helper.Helper.SaveImage(imagePath, imageCreateViewModel.Image.InputStream); 

     if (success) 
     { 
      Image image = new Image 
      { 
       Collection = ds.Single<Collection>(c => c.CollectionId == imageCreateViewModel.CollectionId), 
       Description = imageCreateViewModel.Description, 
       Location = contentPath, 
       Order = Helper.Helper.GetImageOrder(imageCreateViewModel.CollectionId) 
      }; 

      ds.InsertOnSubmit<Image>(image); 
      ds.SubmitChanges(); 
     } 

     else 
      //TODO: Write Error to them 
      success = false; 
    } 

    return RedirectToAction("Collection"); 

} 

但是,當我生成這個方法的視圖它不僅具有abilty操縱一個

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" })) 
{ 
    @Html.ValidationSummary(true) 
    <fieldset> 
     <legend>New Image</legend> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Description) 
     </div> 
     <div class="editor-field"> 
      @Html.EditorFor(model => model.Description) 
      @Html.ValidationMessageFor(model => model.Description) 
     </div> 

     <div class="editor-label"> 
      @Html.LabelFor(model => model.Image) 
     </div> 
     <div class="editor-field"> 
      @Html.ValidationMessageFor(model => model.Image) 
      <input type="file" name="Image" /> 
     </div> 

     <p> 
      <input type="submit" value="Create" /> 
     </p> 
    </fieldset> 
} 
+0

不知道是不是ASP明確,但一般可以通過陣列在POST中通過將字段的名稱設置爲數組標識符。即''這工作在PHP和我想你可以做同樣的或類似的ASP。想想你是否編碼過 - 你會有'Image [] = someImage; Image [] = someOtherImage; Image [] = anotherImage',它爲您留下一系列圖像。 – 2012-03-13 17:50:59

回答

3

下面是一些代碼,我在我的網站用來上傳多張圖片:


好了,這是怎麼做的一個簡單的例子。最終結果是:

enter image description here

的HTML標記是一個簡單的形式,一個提交按鈕。

@using (Html.BeginForm("Create", "Product", FormMethod.Post, new { enctype = "multipart/form-data" })) { 
    @Html.ValidationSummary() 

    <div class="form-field"> 
     <p>Select pictures:</p> 
     <div class="upload-container"> 
      <div class="upload"> 
       <input type="file" name="files" id="file1" /> 
       <img src="@Url.Content("~/Public/images/delete.png")" alt="Remove picture." /> 
      </div> 
     </div>   
    </div> 

    <div class="form-field"> 
     <input type="submit" value="Create" /> 
    </div> 
} 

我們還需要一些jQuery的魔力,因此每次有人添加圖像,讓我們需要他們還可以添加更多。用戶可以上傳N張圖像。我們使用的on()方法,這樣的事件每一個新創建的元素結合上。添加輸入

公告名稱爲「文件」,我們在ActionMethod使用相同的名稱。

<script type="text/javascript"> 
    $(document).ready(function() { 
     var currentImage = 1; 
     $("body").on("change", "input[name='files']", function() { 
      var pathToRemoveIcon = "@Url.Content("~/Public/images/delete.png")"; 
      currentImage = currentImage + 1; 
      var htmlToAppend = '<div class="upload"><input type="file" name="files" id="file' + currentImage + '" /><img src="' + pathToRemoveIcon + '" alt="Remove picture." /></div>'; 
      $('.upload-container').append(htmlToAppend); 
     }).on("click", ".upload img", function() { 
      if ($(this).parent().siblings().length > 0) { 
       $(this).parent().remove();  
      } 
     }); 
    }); 
</script> 

最後,我們收到我們要綁定的模式,也文件的枚舉的控制器代碼:

[HttpPost] 
public ActionResult Create(ProductModel model, IEnumerable<HttpPostedFileBase> files) 
{ 
    try 
    { 
     if (ModelState.IsValid) 
     { 
      foreach (var file in files) 
      { 
       // Verify that the user selected a file 
       if (file != null && file.ContentLength > 0) 
       { 
        // extract only the filename 
        var fileName = Path.GetFileName(file.FileName); 

        // etc. 
       } 
      } 
     } 
     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(model); 
    } 
} 
+0

這實際上並不奏效,因爲它們還必須添加其他信息。 – ediblecode 2012-03-13 18:14:08

+0

@danRhul:編輯ActionMethod的簽名來說明如何綁定典型的POCO模型和上傳的文件。 :)這工作得很好,我一直在網站上使用它。 – 2012-03-13 18:15:12

+0

我是指每個人的形象?這將如何工作? – ediblecode 2012-03-13 18:35:23

0

L:在時間(我來編輯,以允許他們上載的圖像)圖像VC將允許您通過接受HttpPostedFileBase對象列表來接受多個文件上傳。您需要確保所有文件上傳控件的名稱與您的操作方法的參數名稱相同。

public ActionResult UploadFiles(IEnumerable<HttpPostedFileBase> files) 
{ 
} 
+0

爲什麼downvote? – 2012-03-13 17:59:36

+0

Upvoted你,這是正確的答案。 – 2012-03-13 18:12:04

1

我不知道這是否會轉移到正確生成模型,但是如果你能夠使用HTML5,那麼你可以做使用input multiple屬性允許多於一個的輸入。它不是在鉻我承認可怕的漂亮,不過,

Here is the documentation

And, here is a decent example that makes things a little prettier

+0

非常有趣 – ediblecode 2012-03-13 18:06:50

+2

-1 W3Schools的鏈接。在這裏閱讀:http://w3fools.com/ – 2012-03-13 18:12:21

+1

謝謝你的信息。我已經更新了我的答案,指出了現在的w3文檔。我會看看我能否找到一個不同的互動示例。請刪除downvotes :) – 2012-03-13 18:19:17

-1

您可以上傳一個帖子的多個文件。

只需爲每個文件上傳一個不同的文件上傳名稱,然後在控制器中執行Request.Files的foreach。一些類似於:

foreach (var file in Request.Files) 
{ 
    if (file.ContentLength > 0) 
    ... do something ... 

} 

Here a sample