Home > database >  how to Upload the file during for loop
how to Upload the file during for loop

Time:11-04

I have a list in which I upload a file for each record with Ajax, but because I am in a loop and I used ID for input, only the first record file is uploaded and the rest of the records are not uploaded.Please check the code

I have a list in which I upload a file for each record with Ajax, but because I am in a loop and I used ID for input, only the first record file is uploaded and the rest of the records are not uploaded.Please check the code

public class TaxParvande
{
    public int id { get; set; }

    public int projectId { get; set; }

    public String projectName { get; set; }

    public int listId { get; set; }

    public int year { get; set; }
    public bool state { get; set; }
    [NotMapped]
    public IFormFile? prosessMastand { get; set; }
    public int prosessId { get; set; }

    public String prosessName { get; set; }
    public String FilePath { get; set; }
  
    public String NaoaParvane { get; set; }
}
    <form asp-controller="Tax" asp-action="SabtEditTaxParvanedAsync" method="post" enctype="multipart/form-data">


        <div  style="overflow: auto; overflow-x: hidden; direction:ltr ">

            <table  width="100%" style="direction:rtl;font-size:12px">
                <thead>

                    <tr  style="background-color: #416992; color: white; position: sticky; top: 0;">

                        <th style="width:150px">وضعیت</th>
                        <th>پروسه پرونده</th>
                        <th>مستندات</th>
                        <th>تاریخ</th>

                    </tr>

                </thead>
                @{ var count = 0;}

                @for (var i = 0; i < Model.Count(); i  )

                {
            <tr>
                <td style="width:150px">

                    <label >
                        <input type="checkbox" onchange="DisableRow(this)" asp-for="@Model.ToList()[i].state" value="True">
                        <span ></span>
                    </label>
                </td>

                <td style="font-size: 12px">
                    <span>@Model.ToList()[i].prosessName</span>
                    <input  value="@Model.ToList()[i].prosessName" name="[@i].prosessName" />

                </td>

                <td>
                    <div >
                        <div>

                            <span  id="spnImageCartMlie" style="color: black;font-size: 12px"></span>

                        </div>
                        <div>
                            <input type="button" required onclick="UploadImage()" value="Upload"  id="btnUpLoad" />

                            <div id="divmessage" ></div>


                        </div>

                        <input id="mostanadPath" name="[@i].prosessMastand" type="file" >
                    </div>

                </td>
                <td style="font-size: 12px" hidden>
                    <span>@Model.ToList()[i].prosessId</span>
                    <input  value="@Model.ToList()[i].prosessId" name="[@i].prosessId" />
                </td>

                <td>
                </td>


            </tr>
                    count  ;
                }



            </table>
        </div>


        <div >
            <button  type="submit">ثبت اطلاعات</button>
        </div>

    </form>
//--------------------------------------------------------------------------

  [HttpPost]
    public async Task<IActionResult> SabtEditTaxParvanedAsync([FromForm]IEnumerable<TaxParvande> taxParvandes)
    {
        if (taxParvandes == null)
        {
            return Content("File not selected");
        }
        foreach (var item in taxParvandes)
        {
            var path = Path.Combine(_webHostEnvironment.WebRootPath, "ListUpload", item.prosessMastand.FileName);
            using (FileStream stream = new FileStream(path, FileMode.Create))
            {
                await item.prosessMastand.CopyToAsync(stream);
                stream.Close();
            }

           
            var taxparvand = new TaxParvande
            {
                prosessId =item.prosessId,
                prosessName = item.prosessName,
                state = item.state,                    
                FilePath = path,
            };
            _context.Add(taxparvand);
            await _context.SaveChangesAsync();
        }
     

        return View();
    }

enter image description here

CodePudding user response:

Update:

Based on your comment, here is the complete view along with additional explanations:

@model IEnumerable< DotNet6MVCWebApp.Models.TaxParvande>
<form asp-controller="YourContorllerName" asp-action="SabtEditTaxParvanedAsync" method="post" enctype="multipart/form-data">
    <div  style="overflow: auto; overflow-x: hidden; direction:ltr ">

        <table  width="100%" style="direction:rtl;font-size:12px">
            <thead>

                <tr  style="background-color: #416992; color: white; position: sticky; top: 0;">

                    <th style="width:150px">وضعيت</th>
                    <th>پروسه پرونده</th>
                    <th>مستندات</th>
                    <th>تاريخ</th>

                </tr>

            </thead>
            @{
                var count = 0;
            }

            @for (var i = 0; i < Model.Count(); i  )

            {
                <tr>
                    <td style="font-size: 12px" hidden>
                        <span>@Model.ToList()[i].prosessId</span>
                        <input  value="@Model.ToList()[i].prosessId" name="[@i].prosessId" />

                    </td>
                    <td style="width:150px">

                        <label >
                            <input type="checkbox" onchange="DisableRow(this)" asp-for="@Model.ToList()[i].state" value="True">
                            <span ></span>
                        </label>
                    </td>

                    <td style="font-size: 12px">
                        <span>@Model.ToList()[i].prosessName</span>
                        <input  value="@Model.ToList()[i].prosessName" name="[@i].prosessName" />

                    </td>

                    <td>
                        <div >
                            <div>

                                <span  id="spnImageCartMlie" style="color: black;font-size: 12px"></span>

                            </div>
                            <div>
                                <input type="button" required onclick="UploadImage()" value="Upload"  id="btnUpLoad" />

                                <div id="divmessage" ></div>


                            </div>

                            <input id="mostanadPath" name="[@i].prosessMastand" type="file" >
                        </div>

                    </td>


                    <td>
                    </td>


                </tr>
                count  ;
            }

        </table>
    </div>

    <div >
        <button  type="submit"> Submit ثبت اطلاعات</button>
    </div>

</form>

IWebHostEnvironment:

Regarding the error on _environment you could replace to your constructor name this error is obvious as our constructor name was different. As I kept the name as below:

 private readonly IWebHostEnvironment _environment;

You can set anything convenient for you.

Controller Name:

Even if you set controller action as SabtEditTaxParvaned it will works because it will check if there os any POST method within the controller. It will not works if there are many POST action. However, you can replace it to SabtEditTaxParvanedAsync

Previous Answer:

I have a list in which I upload a file for each record with Ajax, but because I am in a loop and I used ID for input, only the first record file is uploaded and the rest of the records are not uploaded

Based on your shared code it appeared that, you have two scenario

  1. Single Upload When Click on Upload Button
  2. All Upload Together When Click on Submit Button

As I have checked Single Upload which seems working as expected. However, for List Upload or All Upload you should required few modification in your code. Please follow the steps below:

Model For List Upload:

public class TaxParvande
    {
        public IFormFile? prosessMastand { get; set; }
        public int prosessId { get; set; }  
        public bool state { get; set; }  
        public string prosessName { get; set; }
    }

Note: As you said "In a loop and I used ID for input" Therefore, I have added prosessId which we will use in View later on.

Controller:

    [HttpPost]
    public async Task<IActionResult> SabtEditTaxParvanedAsync([FromForm]IEnumerable<TaxParvande> taxParvandes)
    {
        if (taxParvandes == null)
        {
            return Content("File not selected");
        }
        foreach (var item in taxParvandes)
        {
            var path = Path.Combine(_environment.WebRootPath, "ListUpload", item.prosessMastand.FileName);
            using (FileStream stream = new FileStream(path, FileMode.Create))
            {
                await item.prosessMastand.CopyToAsync(stream);
                stream.Close();
            }

           
            var taxDomainModel = new TaxDomainModel
            {
                prosessId =item.prosessId,
                prosessName = item.prosessName,
                state = item.state,                    
                FilePath = path,
            };
            _context.Add(taxDomainModel);
            await _context.SaveChangesAsync();
        }
     

        return View();
    }

Note: As you are submitting FormData thus we should redefine the controller as [FromForm] and the List of IEnumerable<TaxParvande>. As it is list therefore, we are looping through the items and saving image in folder finally getting the path location so that we can save in database.

View:

In View we will modify two things.

Firstly, for Multiple FromData we should use this attribute enctype="multipart/form-data" to submit bulk file at once. Final change would as below

<form asp-controller="LoopUpload" asp-action="SabtEditTaxParvaned" method="post" enctype="multipart/form-data">

Secondly, Use additional one td for prosessId and set the attribute as hidden just as below:

  <td style="font-size: 12px" hidden>
       <span>@Model.ToList()[i].prosessId</span>
       <input  value="@Model.ToList()[i].prosessId" name="[@i].prosessId" />
  </td>

Note: You are all done to to upload a list together now. You can see the output below.

Output:

enter image description here

  • Related