2012-03-13 5 views
0

私はこのサイトのユーザーに同時に複数の画像をアップロードすることをお勧めします。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"); 

} 

しかし、私はこの方法のためのビューを生成するとき、それは一つだけを操作する付ける機能を持っています(画像をアップロードできるように編集する必要があります):

@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'。イメージの配列が残っています。 –

答えて

3

ここで私は複数の画像をアップロードするために自分のサイト上で使用されるいくつかのコードです:ので、これはそれを行う方法についての簡単な例で、


OKを。最終結果:

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

+0

@danRhul:ActionMethodのシグネチャを編集して、標準的なPOCOモデルとアップロードされたファイルをバインドする方法を示します。 :)これはうまく動作し、私はいつもウェブサイトでそれを使用します。 –

+0

私はそれぞれの個々のイメージを意味しましたか?これはどのように機能しますか? – ediblecode

0

M VCは、HttpPostedFileBaseオブジェクトのリストを受け入れることで、アクション内で複数のファイルアップロードを受け入れることができます。すべてのファイルアップロードコントロールがアクションメソッドの引数と同じ名前になっていることを確認する必要があります。

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

なぜdownvote? –

+0

あなたをアップしましたが、これは正解です。 –

1

私は、これは適切にモデルを生成する介して転送するかどうかわからないが、あなたはHTML5を使用することができます場合は、複数の入力を可能にするためのinput multiple属性を使用して行うことができます。それは可能ですが、あなただけの自動表示を足場よりも多くの仕事を持ってしようとしている

Here is the documentation

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

+0

非常に興味深い – ediblecode

+2

-1のw3schoolsリンクです。ここをクリックしてください:http://w3fools.com/ –

+1

情報をありがとうございます。私は今のところw3からのドキュメントを指すように私の答えを更新しました。別のインタラクティブな例が見つかるかどうかがわかります。 downvotesを削除してください:) –

2

けれどもそれは、私が認めるクロームで恐ろしくかなりイマイチ。以下はPhil Haackのブログ記事で、MVCやコレクションのModelBindingに親しみやすいHTMLビューを構築する方法を詳しく解説しています。

http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx

トピックのスコット・Hanslemanによって別のポスト。 http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

-1

複数のファイルを1つの投稿でアップロードできます。

それぞれのファイルアップロード名をそれぞれ別々に設定するだけで、コントローラではRequest.Filesにforeachを実行します。それに似た何か:

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

} 

Here a sample

関連する問題