Home > Enterprise >  ASP.Net MVC 5 with DropZone Can't Send Additional Parameters to Controller
ASP.Net MVC 5 with DropZone Can't Send Additional Parameters to Controller

Time:11-16

Ok, I am sure this already has an answer somewhere, but I can honestly tell you that everything I have tried, has failed. Here is my current configuration:

Shared _Layout.cshtml (below the footer)

<script src="~/lib/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/js/site.js" asp-append-version="true"></script>
    <script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
    @await RenderSectionAsync("Scripts", required: false)

Images View

@model NewProductVM
<form id="form2" method="post" enctype="multipart/form-data" data-parsley-validate class="form-horizontal form-label-left">    
    <div class="form-group">
        <label class="control-label col-md-2" for="first-name">
             <span class="required">*</span>
        </label>
        
        <input type="hidden" value="@Model.Id" />

        <div class="col-md-6" id="dropzone">
            <div action="UploadFiles" class="dropzone" id="uploader">
                Drop files here or click to upload.<br>
            </div>
        </div>
    </div>
</form>

Products Controller

[HttpPost]
public async Task<IActionResult> UploadFiles(string Id)
{
            bool bSuccess = true;            

            _ConnectionString = _Configuration.GetConnectionString("StorageConnectionString");
            _ContainerName = _Configuration.GetValue<string>("StorageContainerName");

            string uploads = Path.Combine(_hostingEnvironment.ContentRootPath, "Uploads");

            if (!Directory.Exists(uploads))
                Directory.CreateDirectory(uploads);

            foreach (var iFormFile in Request.Form.Files)
            {
                if (iFormFile.Length > 0)
                {
                    if (StorageHelper.IsImage(iFormFile))
                    {
                        var filePath = Path.Combine(uploads, iFormFile.FileName);
                        using (var stream = new FileStream(filePath, FileMode.Create))
                        {
                            await iFormFile.CopyToAsync(stream);
                        }

                        bSuccess = await StorageHelper.UploadFileToStorage(iFormFile, filePath, _ConnectionString, _ContainerName);
                        System.IO.File.Delete(filePath);

                        ProductImage productImage = new ProductImage
                        {
                            ProductId = int.Parse(Id),
                            ImageURL = $"{_Configuration.GetValue<string>("StorageContainerURL")}/{iFormFile.FileName}"                            
                        };

                        await _imageService.AddNewImageAsync(productImage);                        
                    }
                }
            }
            return RedirectToAction("Index");
}

I would really like to pass the entire NewProductVM model to the UploadFiles method, but there are not very many properties in the view model, so I could pass each property individually.

Right now I am taking someones suggestion to create a hidden form field and add a value I want to pass to the controller as a form field, but the parameter value in the UploadFiles method is null. I have also tried using asp-route-id="@Model.Id". When I did that, the value of id was 0 in the controller method.

Anyone have any suggestions?

CodePudding user response:

Ok, I finally found the answer and I cannot believe how simple it was. I have been working on this for several hours. I found the answer here: https://social.msdn.microsoft.com/Forums/en-US/a87c6936-c0b5-4f47-b074-dbaf4c154cdd/id-parameter-returning-null-after-using-formdataappend-to-append-id-to-model-id-in-mvc-5?forum=aspmvc

This is what I did:

Images.cshtml

<form id="form2" method="post" enctype="multipart/form-data" data-parsley-validate class="form-horizontal form-label-left">
    <div class="form-group">
            
        <label class="control-label col-md-2" for="first-name">
            <span class="required">*</span>
        </label>

        <div class="col-md-6" id="dropzone">
            <div action="[email protected]" class="dropzone" id="uploader">
                Drop files here or click to upload.<br>
            </div>

        </div>
    </div>
</form>   

ProductsController.cs

[HttpPost]        
public async Task<IActionResult> UploadFiles(int Id)
{
    bool bSuccess = true;            

    _ConnectionString = _Configuration.GetConnectionString("StorageConnectionString");
    _ContainerName = _Configuration.GetValue<string>("StorageContainerName");

    //int Id = int.Parse(fc["Id"]);

    string uploads = Path.Combine(_hostingEnvironment.ContentRootPath, "Uploads");

    if (!Directory.Exists(uploads))
        Directory.CreateDirectory(uploads);

    foreach (var iFormFile in Request.Form.Files)
    {
        if (iFormFile.Length > 0)
        {
            if (StorageHelper.IsImage(iFormFile))
            {
                var filePath = Path.Combine(uploads, iFormFile.FileName);
                using (var stream = new FileStream(filePath, FileMode.Create))
                {
                    await iFormFile.CopyToAsync(stream);
                }

                bSuccess = await StorageHelper.UploadFileToStorage(iFormFile, filePath, _ConnectionString, _ContainerName);
                System.IO.File.Delete(filePath);

                //ProductImage productImage = new ProductImage
                //{
                //    ProductId = Id,
                //    ImageURL = $"{_Configuration.GetValue<string>("StorageContainerURL")}/{iFormFile.FileName}"          
                //};

                //await _imageService.AddNewImageAsync(productImage);                        
            }
        }
    }
    return RedirectToAction("Index");
}

The part that really made it work was action="[email protected]".

So basically, I am using the action to pass the values I want to my controller method.

  • Related