【问题标题】:Posting form with input fields and multiple files selected using jQuery AJAX in ASP.NET Core在 ASP.NET Core 中使用 jQuery AJAX 选择输入字段和多个文件的发布表单
【发布时间】:2019-01-26 20:42:07
【问题描述】:

我正在尝试在用户完成选择多个文件后立即使用 jQuery AJAX 在 ASP.NET Core 中手动发布表单。我正在使用的 Uploader 有一个“selected”事件,我想使用 jQueryAJAX 将表单发布到服务器。

当向表单添加提交按钮并在 UI 上单击它时,此完全相同的表单会完美地发布到服务器。 Files 已绑定,ProductId 已绑定。但是,我试图避免页面闪烁。作为替代解决方案,我通过调用提交表单: $("#form").submit();在 onSelect 函数中而不是在 AJAX 请求中。

模型如下所示:

public int ProductId { get; set; }
public IList<IFormFile> Files { get; set; }

表单如下所示:

<form method="post" enctype="multipart/form-data">
     <ejs-uploader id="Files" showFileList="false" autoUpload="false" multiple="true" selected="onSelected" success="onSuccess" allowedExtensions=".doc, .docx, .pdf, .jpg, .jpeg, .png"></ejs-uploader>
     <input asp-for="ProductId" type="hidden" />
</form>

这是我一直在尝试但不起作用的 JavaScript:

    function onSelected(args) {
        var files = args.filesData;
        var formData = new FormData();

        for (var i = 0; i != files.length; i++) {
            formData.append("files[]", files[i]);
        }

        $.ajax({
            type: "POST",
            contentType: false,
            url: '?handler=FileUpload',
            data: formData,
            processData: false,
            headers: {
                RequestVerificationToken:
                    $('input:hidden[name="__RequestVerificationToken"]').val()
            },
            success: function (data) {

            },
        });

        //$("#form").submit();
    }

我用的是razer pages所以操作方法是:

[BindProperty]
public int MessageId { get; set; }

[BindProperty]
public IList<IFormFile> Files { get; set; }

public async Task<ActionResult> OnPostAsync()
{
}

我也尝试过创建一个视图模型:FileUploadViewModel,其中包含相同的 2 个属性。

public async Task<ActionResult> OnPostAsync(FileUploadViewModel vm)
{
}

【问题讨论】:

  • 请出示您的操作方法
  • @CamiloTerevinto 我上传了一些关于 Action 方法的附加信息。我正在使用与 MVC 略有不同的剃须刀页面。页面本身具有属性,因此可以消除视图模型。但是,我也尝试将 ViewModel 作为参数。没有什么是有约束力的。这篇文章是我发现的最接近我想要做的事情,但他只为一个文件做这件事。此外,我什至无法正常工作。 learnrazorpages.com/razor-pages/ajax/upload-files
  • 嗯,我不确定 Razor Pages,但在 MVC 中这是错误的。你需要一个[FromForm] FileUploadViewModel vm,虽然这可能是默认值
  • 想一想,你应该使用formData.append("Files", files[i]);

标签: javascript c# jquery asp.net-core


【解决方案1】:

我参加聚会可能有点晚了,但是我遇到了完全相同的问题,我想使用 ajax 手动发布我的请求以及用户输入的任何表单值以及任何要上传的选定文件。

因为我是使用 ajax 手动调用控制器,所以没有包含文件。
这是我的 ajax 发布请求。

 $.ajax({
        type: 'POST',
        url: '/home/createorder',
        data: new FormData(document.forms[0]),
        contentType: false,
        processData: false,
        crossDomain: true,
        success: function (data) {
               console.log(data);
               window.location.replace(data.redirectUrl);
        },
        error: function (data) {
                console.log(data);
                alert(data.responseJSON.error);
        },
 })

这是我的模特的财产。

public IReadOnlyCollection<IFormFile> AttachmentCollection { get; set; }

最后这是我的cshtml页面构成

 <div class="card card-5">
        <div class="card-heading">
            <h2 class="title">Attachments</h2>
        </div>
        <div class="card-body">
            <div class="form-row">
                <div class="custom-file">
                    <input asp-for="AttachmentCollection" class="form-control custom-file-input" multiple>
                    <label class="custom-file-label">Choose File...</label>
                </div>
            </div>
        </div>
    </div>

注意:确保在您的 &lt;form&gt; 中包含此 enctype="multipart/form-data"

【讨论】:

    【解决方案2】:

    根据FormData.append(),我认为你必须使用

    formData.append("files[]", files[i]);
    

    代替

    formData.append("files", files[i]);
    

    要追加多个文件...

    【讨论】:

    • 我试过了,但最终还是得到了 0 个文件的列表。知道我的ajax请求是否还有其他问题吗?我什至不确定 processData 和 contentType 是否都应该为假。我在另一篇文章中看到了这一点。
    • 你在开玩笑吗?文档说and being compatible with PHP's naming conventions。你在哪里看到 PHP?
    • As with regular form data, you can append multiple values with the same name. 并在括号中指向 PHP 以...改变你的眼镜人
    • 只是一个变量名,这么难理解吗?这就像说将int myName = "asd"; 更改为int someInt = "asd" 会突然起作用,那些[] 在那里毫无用处
    【解决方案3】:

    您可以将附件作为 IEnumerable 类型的单独控制器参数接收,请注意,为了正确完成映射,您必须为 html 输入文件控件选择正确的命名,例如,如果您的控制器将具有以下签名

    public ActionResult SaveProduct(Product newproduct , IEnumerable<HttpPostedFileBase> files) 
    

    那么html输入控件必须命名为:

    <input type='file' name='files[0]'/>
    <input type='file' name='files[1]'/>
    <input type='file' name='files[2]'/>
    

    等等

    不知道是否有一个选项可以直接将控件绑定到模型而不创建自定义模型绑定器,但我一直使用这个选项,相当简单和容易

    【讨论】:

    • 我需要从单个文件输入上传多个文件。
    • HttpPostedFIleBase 不是 ASP.NET Core。 ASP.NET Core 使用 IFormFile
    • 然后您可以创建一个输入控件并将其映射到 IEnumerable 或布莱克建议的 IFormFile 类型的一个动作参数跨度>
    猜你喜欢
    • 1970-01-01
    • 2012-06-19
    • 2016-10-12
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 1970-01-01
    • 2014-10-14
    相关资源
    最近更新 更多