带有 Razor Pages 的 Dropzone 未将文件提交到 HttpContext.Request.Form.Files

问题描述 投票:0回答:1

我一直在努力在我的 razor 页面上实现 dropzone.js。我目前正在尝试创建一个帮助台,其中 dropzone 允许用户拖动文件以连同其票证一起上传。我没有太多运气将文件上传到剃刀页面的后端。我可以让它与常规 标签一起使用,但不能与 dropzone 一起使用。 HttpContext.Request.Form.Files 属性为空,如果我绑定 IformFile 列表,或者至少尝试绑定,我也不会获取该文件。

我很幸运地将文件显示在单独控制器中的 Form.Files 中,但我不确定如何将文件位置从控制器传递到在后端处理的帮助票证。我知道我可以在后端处理整个表单上传,但我将对所有表单的文件上传进行更改,如果我必须有一个控制器,它应该能够仅处理文件上传部分和然后返回razor后端完成剩余的表单提交 文件上传保存在我的 wwwroot 文件夹中名为“附件”的文件夹中,然后我有一个票证上传模型,用于存储它们的位置以及与之关联的票证(每个票证可以有多个上传),所以我必须有某种方式来处理在其模型中创建帮助票证,然后创建文件上传及其位置。

这是我的代码的相关部分:

首先是我的拖放区配置:

$(document).ready(function () { 
    Dropzone.autoDiscover = false;
    console.log(window.location.pathname); // path returned here is what is put in url. Will use for other razor pages implementing this in the future?
    $("#fileUploadArea").dropzone({
        url: "/api/fileupload", // or to razor backend: /IT/Help (matches location.pathname)
        autoProcessQueue: false,
        addRemoveLinks: true,
        acceptedFiles: ".png,.jpg,.gif,.jpeg,.bmp",
        uploadMultiple: true,
        maxFiles: 10,
        headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
        paramName: "files",
        init: function () {
            var myDropzone = this;
            myDropzone.options.addRemoveLinks = true;
            myDropzone.options.dictRemoveFile = "Remove";
            //myDropzone.paramName = () => "files";
            this.on("success", function (file, response) {
                alert("success");                
            });
            this.on("error", function (file, errorMsg) {
                alert("error");
                console.error(errorMsg);
            });
            //Manually submit form with files?
            $('#wmf-help-submit-button').on('click', function (e) {
               myDropzone.processQueue();
            });
        }
    });
    
});

形式:

<form method="POST" enctype="multipart/form-data" class="" id="ticketForm" asp-action="/Index">
    @* @Html.AntiForgeryToken(); *@
    <head>
        <title></title>
    </head>
    <body>
        <!-- Two inputs, one for a title and another for a body/description omitted -->

                <!-- Image Uploads -->

                <div class="col-12 text-dark">
                    <p>Please upload any screenshots below:</p>
                    <div id="fileUploadArea" class="dropzone text-center">
                       <!-- <input type="file" name="Uploads" accept=".jpg, .jpeg, .png" multiple hidden> -->
                        <span class="dz-message">Drop files here or <span class="text-decoration-underline">Click to browse</span></span>
                    </div>
                    <!-- TODO: implement fallback for no js? Non-DZ way that works. -->
                    <!-- <label for="image_uploads">Choose images to upload (PNG, JPG)</label>
                    <div id="wmf-files-to-upload">
                    <input type="file" name="Uploads" accept=".jpg, .jpeg, .png" multiple>
                    </div> -->

                </div>
                <div class="col-12 text-center mt-4 mb-2">
                    <input id="wmf-help-submit-button" class="wmf-button-main btn form-control text-center" type="submit" />
                </div>
                
</form>

我有一个剃刀后端,如下所示:

namespace mynamespacehere
{
    [Authorize]
    public class IndexModel : PageModel
    {
        private readonly IUnitofWork _unitofWork;
        private readonly IWebHostEnvironment _webHostEnvironment;
        
        /* Irrelevant fields removed */

        public HelpDeskTicket HelpTicket { get; set; }
        [BindProperty]
        public List<IFormFile> Uploads {  get; set; } // DZ uploads don't show here either.

/* ... Get method omitted */

        public async Task<IActionResult> OnPost()
        {
/* ... handling other form fields validation */

/* ... Created help ticket in DB (Help ticket does not have upload as part of it's model, upload references ticket instead) */

/* file upload area. files put in via dropzone are not showing here. */

            // Upload Files if there are any. Could be in a controller instead?
            // YOU MUST ALWAYS UPLOAD FILES AFTER COMMITTING INITIAL TICKET TO DB OTHERWISE THERE WILL NOT BE A
            // TICKETID TO ASSOCIATE WITH THE UPLOADS!
            #region File Upload
            var files = HttpContext.Request.Form.Files;
            if (files.Count > 0)
            {
                string webRootPath = _webHostEnvironment.WebRootPath;


                foreach (var file in files)
                {
                    HelpDeskTicketUpload ticketUpload = new HelpDeskTicketUpload();

                    string fileName = Guid.NewGuid().ToString();
                    var uploadpath = Path.Combine(webRootPath, @"attachments\helpdesk\");
                    var extension = Path.GetExtension(file.FileName);
                    var filePath = uploadpath + fileName + extension;
                    using var fileStream = System.IO.File.Create(filePath);
                    file.CopyTo(fileStream);

                    ticketUpload.HelpDeskTicketId = HelpTicket.Id;
                    ticketUpload.Filetype = extension;
                    ticketUpload.Location = @"\attachments\helpdesk\" + fileName + extension;
                    _unitofWork.HelpDeskTicketUpload.Add(ticketUpload);
                }
            }

            #endregion


            TempData["success"] = "Your help desk message was sent successfully!";
            return RedirectToPage("./Index");
        }

    }
}

可以获取文件的控制器,但我不知道如何传递给razor进行表单处理:

namespace mynamespacehere
{
    [Route("api/[controller]")]
    [ApiController]
    public class FileuploadController : Controller
    {
        private readonly UnitofWork _unitOfWork;
        private readonly IWebHostEnvironment _webHostEnvironment;
        public FileuploadController(UnitofWork unitofWork, IWebHostEnvironment webHostEnvironment)
        {
            _unitOfWork = unitofWork;
            _webHostEnvironment = webHostEnvironment;
        }

        [HttpPost]
        public async Task<IActionResult> SaveFile()
        {
            var files = HttpContext.Request.Form.Files;
            //var filesReq = HttpContext.Request.Form.Files;
            if (files.Count > 0)
            {
                string webRootPath = _webHostEnvironment.WebRootPath;


                foreach (var file in files)
                {
                    HelpDeskTicketUpload ticketUpload = new HelpDeskTicketUpload();

                    string fileName = Guid.NewGuid().ToString();
                    var uploadpath = Path.Combine(webRootPath, @"attachments\helpdesk\");
                    var extension = Path.GetExtension(file.FileName);
                    var filePath = uploadpath + fileName + extension;
                    using var fileStream = System.IO.File.Create(filePath);
                    file.CopyTo(fileStream); //Not showing up in filepath need to debug this but can be considered a separate issue.
                }
            }

            return Ok("upload successful"); //Don't know how to return response/file locations to post backend.
        }
    }
}

回顾一下,我有两种我真正想问的方法。首先是将来自 Dropzone 的文件上传到剃刀后端,第二个是,如果我必须使用控制器,我将如何将文件位置(可能上传了多个文件)传回剃刀,然后索引到数据库。

html asp.net asp.net-core-mvc razor-pages dropzone.js
1个回答
0
投票

下面是razor页面的工作演示,大家可以参考一下。

<form method="POST" enctype="multipart/form-data" class="" id="ticketForm">
    <div id="fileUploadArea" class="my-dropzone">       
        <span class="dz-message" >Drop files here or <span class="text-decoration-underline" >Click to browse</span></span>
    </div>
   
    <div class="col-12 text-center mt-4 mb-2">
        <input id="wmf-help-submit-button" class="wmf-button-main btn form-control text-center" type="submit" />
    </div>
</form>
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
<link rel="stylesheet"
      href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css"
      type="text/css" />
<script>   
    // Dropzone has been added as a global variable.
    const dropzone = new Dropzone("div.my-dropzone", {
        url: "/Index",
        autoProcessQueue: false,
        addRemoveLinks: true,
        acceptedFiles: ".png,.jpg,.gif,.jpeg,.bmp",
        uploadMultiple: true,
        maxFiles: 10,
        parallelUploads: 100,
        maxFiles: 100,
        headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
        paramName: "files",
        init: function () {
            var myDropzone = this;
            myDropzone.options.addRemoveLinks = true;
            myDropzone.options.dictRemoveFile = "Remove";
            //myDropzone.paramName = () => "files";
            this.on("success", function (file, response) {
                alert("success");
            });
            this.on("error", function (file, errorMsg) {
                alert("error");
                console.error(errorMsg);
            });
            //Manually submit form with files?
            $('#wmf-help-submit-button').on('click', function (e) {
                 e.preventDefault();
                myDropzone.processQueue();
            });
        }      
    });
    
</script>

剃刀后端结果:

© www.soinside.com 2019 - 2024. All rights reserved.