1

Good day/night, dear SOers,

I stuck with dynamically added file uploads inside the form in ASP.NET MVC. I create the form with dynamically added controls (insert rows in the table). One of them is file upload. The controls are added via this jQuery function:

$('#addRow').on('click', function () {
    var counter = $('.itemRow').length;
    $('#itemstable').append('<tr class="itemRow"> <td><select required name="ItemsList[' + counter + '].ProgramNameShort">@foreach (SelectListItem item in ViewBag.VBprograms) { <option value="@item.Value">@item.Text</option>} </select></td>' +
        '<td><input type="text" name="ItemsList[' + counter + '].ItemName" /></td>' +
        '<td><input type="text" name="ItemsList[' + counter + '].ItemProducer" /></td>' +
        '<td><input type="text" name="ItemsList[' + counter + '].ItemQty" /></td>' +
        '<td><input type="text" name="ItemsList[' + counter + '].Additional" /></td>' +
        '<td><input type="text" name="ItemsList[' + counter + '].Comments" /></td>' + 
        '<td><input type="file" name="ItemsList[' + counter + '].Image" /></td>' +
        '</tr>');

    counter++;
});

My controller receives ViewModel:

[HttpPost]
public ActionResult Create(CallViewModel callViewModel)

ItemsList with Image as [] byte property is the class inside CallViewModel class. Later the object is saved in the database (DB First approach). As far as I understand, images can be uploaded as HttpPostedFileBase object (or IEnumerable for multiple files uploaded). But how can I handle file uploads uploaded inside such a list? I cannot show all the code as it is multi-step multi-tab form with the table being just a part inside one of tabs. If any parts of the code need to be demonstrated I can update current question.

Many thanks in advance.

UPD Here's the relevant part of CallViewModel class:

        public class CallViewModel
            {
    ... //properties used in other tabs

         public List<ItemClass> ItemsList { get { return _items; } }

         private List<ItemClass> _items = new List<ItemClass>();
public class ItemClass
        {  //Item

            public Guid ItemID { get; set; }

            [Required, Display(Name = "Наименование")]
            public string ItemName { get; set; }

            [Required, Display(Name = "Производитель")]
            public string ItemProducer { get; set; }

            [Required, Display(Name = "Количество")]
            public int ItemQty { get; set; }

            [Display(Name = "Комментарии")]
            public string Comments { get; set; }

            [Required, Display(Name = "Изображение")]
            public HttpPostedFileBase Image { get; set; }

            [Display(Name = "Дополнительно предоставляемые объекты")]
            public string Additional { get; set; }
            //Program
            //[Required, Display(Name = "Полное название")]
            //public string ProgramNameFull { get; set; }

            [Required, Display(Name = "Краткое название")]
            public string ProgramNameShort { get; set; }

            List<Program> Programs { get; set; }
}
}
  • 2
    Your `Image` property needs to be `HttpPostedFileBase` –  Sep 30 '18 at 22:30
  • @Stephen, thanks for your prompt reply and sorry for my rookie question: should it be declared as HttpPostedFileBase Image inside the ViewModel class? – Сергей Чащин Oct 01 '18 at 00:14
  • Yes - `public HttpPostedFileBase { get; set; }` (also suggest you read [Submit same Partial View called multiple times data to controller?](https://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) for better alternatives) –  Oct 01 '18 at 00:17
  • Can you show your model class CallViewModel code? – PNDev Oct 01 '18 at 01:48
  • @PNDev, it's extra large, I'll just post a small part of it with the relevant code (updated after the comment of Stephen Muecke). – Сергей Чащин Oct 01 '18 at 04:34
  • Looks liks you do have not encoding type mentioned. You can do it like below while creating your form element in the view. @using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })). – PNDev Oct 01 '18 at 06:36

2 Answers2

0
    $('#addRow').on('click', function () {
        var counter = $('.itemRow').length;
        $('#itemstable').append('<tr class="itemRow"> <td><select required name="ItemsList[' + counter + '].ProgramNameShort">@foreach (SelectListItem item in ViewBag.VBprograms) { <option value="@item.Value">@item.Text</option>} </select></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].ItemName" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].ItemProducer" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].ItemQty" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].Additional" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].Comments" /></td>' + 
            '<td><input type="file" id="FileUpload ' + counter  + '"   /></td>' +
            '</tr>');

        counter++;
    });
--In controller do -- lengthofRow means no of row into ItemsList collection for(Int i=1; i<lengthofRow ;i++ ) { // from below line you can access you file upload by user . Request.Files["FileUpload" + i ]; }
Raju Mali
  • 185
  • 4
0
    <!--  Please define set property of Item List into Model -->
    <!-- begin snippet:hide: false console: true babel: false   -->
    <!-- language: lang-html -->    


 $('#addRow').on('click', function () {
        var counter = $('.itemRow').length;
        $('#itemstable').append('<tr class="itemRow"> <td><select required name="ItemsList[' + counter + '].ProgramNameShort">@foreach (SelectListItem item in ViewBag.VBprograms) { <option value="@item.Value">@item.Text</option>} </select></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].ItemName" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].ItemProducer" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].ItemQty" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].Additional" /></td>' +
            '<td><input type="text" name="ItemsList[' + counter + '].Comments" /></td>' + 
            '<td><input type="file" id="FileUpload ' + counter  + '"   /></td>' +
            '</tr>');

        counter++;
    });

    <!-- end snippet -->



    <!-- Please attach debugger and check you will all file into Request.File  -->
    <!--[HttpPost]  -->
    <!--public ActionResult Create(CallViewModel callViewModel)  -->
    <!--{  -->
        <!--   Int32 cnt=0;  -->
        <!--   cnt = CallViewModel.ItemsList.Count(); -->
         <!-- for(Int i=1; i<=cnt ;i++ )-->
        <!--  {  -->
            // from below line you can access you file upload by user .
         <!--    Request.Files["FileUpload" + i ];  -->
        <!--  }  -->
    <!--} -->
Raju Mali
  • 185
  • 4