Dropzone 不会将其他字段绑定到 Asp.Net 核心视图模型

Dropzone doesn't bind other fields to Asp.Net Core viewmodel

我正在使用以下 html 渲染拖放区。我的控制器正在接受 IFormFile 和 FileViewModel。但是,dropzone 不会将我接受人名的输入标签绑定到表单提交时的 viewModel。

我还决定 Dropzone.js 是一个非常古老的 Ajax 控件,专为单页应用程序准备。

HTML :

@model Dropzone.Models.FileViewModel
    <form action="/Account/Create" enctype="multipart/form-data" method="POST">
        <input type="text" id ="Username" name ="Username" asp-for="Model.Name" />
        <div class="dropzone" id="my-dropzone" name="mainFileUploader">
            <div class="fallback">
                <input name="file" type="file" multiple />
            </div>
        </div>
    </form>
    <div>
        <button type="submit" id="submit-all"> upload </button>
    </div>

JQuery:

<script>
    Dropzone.options.myDropzone = {
        url: "/Account/Create",
        autoProcessQueue: false,
        uploadMultiple: true,
        parallelUploads: 100,
        maxFiles: 100,
        acceptedFiles: "image/*",

        init: function () {

            var submitButton = document.querySelector("#submit-all");
            var wrapperThis = this;

            submitButton.addEventListener("click", function () {
                wrapperThis.processQueue();
            });

            this.on("addedfile", function (file) {

                // Create the remove button
                var removeButton = Dropzone.createElement("<button class='btn btn-lg dark'>Remove File</button>");

                // Listen to the click event
                removeButton.addEventListener("click", function (e) {
                    // Make sure the button click doesn't submit the form:
                    e.preventDefault();
                    e.stopPropagation();

                    // Remove the file preview.
                    wrapperThis.removeFile(file);
                    // If you want to the delete the file on the server as well,
                    // you can do the AJAX request here.
                });

                // Add the button to the file preview element.
                file.previewElement.appendChild(removeButton);
            });

            this.on('sendingmultiple', function (data, xhr, formData) {
                formData.append("Username", $("#Username").val());
            });
        }
    };
</script>

Dropzone doesn't bind other fields to Asp.Net Core viewmodel

要在上传文件中添加其他字段,您可以使用 the sending eventformData 对象中添加字段的值,而不是 sendingmultiple 事件。

检查以下示例:

public class FileViewModel
{
    public string Name { get; set; }
    public IFormFile File { get; set; }
    public List<IFormFile> Files { get; set; }
}

控制器:

    public IActionResult UploadFile()
    {
        FileViewModel model = new FileViewModel() { Name = "new File" };
        return View(model);
    }

    [HttpPost]
    public IActionResult UploadFile(FileViewModel fileViewModel, List<IFormFile> files)
    {
        try
        {
            if (files.Count > 0)
            {
                //string folderRoot = Path.Combine(_environment.ContentRootPath, "Uploads");
                //string filePath = Guid.NewGuid() + Path.GetExtension(file.FileName);
                //filePath = Path.Combine(folderRoot, filePath);
                //using (var stream = new FileStream(filePath, FileMode.Create))
                //{
                //    await file.CopyToAsync(stream);
                //}
            }
            return Ok(new { success = true, message = "File Uploaded" });
        }
        catch (Exception)
        {
            return BadRequest(new { success = false, message = "Error file failed to upload" });
        }
    }

查看页面:

@model WebApplication6.Models.FileViewModel

@{
    ViewData["Title"] = "UploadFile";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

<h1>UploadFile</h1>
  
<form asp-action="UploadFile" enctype="multipart/form-data" method="POST">
    <div class="form-group">
        @*<label asp-for="Name" class="control-label"></label>
            <input asp-for="Name" class="form-control" />
            <span asp-validation-for="Name" class="text-danger"></span>*@
        <input type="text" asp-for="Name" />
        <div class="dropzone" id="dropzone-form" name="mainFileUploader">
            <div class="fallback">
                <input asp-for="File" type="file" multiple />
            </div>
        </div>
    </div>
    <div class="form-group">
        <button type="button" id="submit-all"> upload </button>
    </div>
</form>
  

添加以下 JQuery 脚本:

@section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <link rel="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/dropzone.css" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/dropzone/5.5.1/dropzone.js"></script>

    <script type="text/javascript">
        Dropzone.options.dropzoneForm = {
            url: "/Test/UploadFile",
            paramName: "file", 
            autoProcessQueue: false,
            uploadMultiple: true,
            parallelUploads: 100,
            maxFiles: 100,
            acceptedFiles: "image/*",
            init: function () {

                var submitButton = document.querySelector("#submit-all");
                var wrapperThis = this;

                submitButton.addEventListener("click", function () {
                    wrapperThis.processQueue();
                });

                this.on("addedfile", function (file) {

                    // Create the remove button
                    var removeButton = Dropzone.createElement("<button class='btn btn-lg dark'>Remove File</button>");

                    // Listen to the click event
                    removeButton.addEventListener("click", function (e) {
                        // Make sure the button click doesn't submit the form:
                        e.preventDefault();
                        e.stopPropagation();

                        // Remove the file preview.
                        wrapperThis.removeFile(file);
                        // If you want to the delete the file on the server as well,
                        // you can do the AJAX request here.
                    });

                    // Add the button to the file preview element.
                    file.previewElement.appendChild(removeButton);
                });
                this.on("sending", function (file, response, formData) {
                    formData.append("Name", $("#Name").val());
                    formData.append("Files", file); 
                });
                //this.on('sendingmultiple', function (data, xhr, formData) {
                //    formData.append("Name", $("#Name").val());
                //});
            }
        };
    </script>
}

结果是这样的: