【问题标题】:Upload file and primitive type to Web Api with ajax使用 ajax 将文件和原始类型上传到 Web Api
【发布时间】:2020-03-18 15:05:09
【问题描述】:

我目前正在尝试将图像文件与带有 ajax 的字符串一起上传到 Asp.Net Core Api,但没有成功。

我看了:https://developer.mozilla.org/en-US/docs/Web/API/FormData/Using_FormData_Objects 并认为在 FormData 对象中同时发送图像文件和字符串很容易,但只接收到图像。

在 javascript 中,我正在附加数据并使用 ajax 帖子发送:

    let formData = new FormData();
    formData.append("code", "123");
    formData.append("userFile", document.querySelector("#imgInput").files[0]);

    $.ajax({
        async: true,
        type: "post",
        data: formData,
        processData: false,
        contentType: false,
        url: "https://localhost:22333/api/postmethod",
        success: function (data, response, jqXHR) {
            console.log(response);
        },
        error: function (jqXHR, response, errorThrown) {

        }
    });

而在 Asp.Net Core 中的方法是:

    [HttpPost]
    [Route("postmethod")]
    public async Task PostMethod(IFormFile code, IFormFile userFile)

我尝试将code 参数设置为IFormFile 和字符串,但没有任何反应。 userFile 参数始终正确设置为 Image 文件,这让我想知道我在上传 code 字符串时做错了什么。

TLDR: 无法通过 ajax 调用将图像文件和字符串同时上传到 Asp.Net Core 3.1 Api。

有没有更好的上传文件和参数的方法?

【问题讨论】:

  • 看看能不能解决问题! :)
  • 对我最初的评论造成的混乱表示歉意。我忘了你必须使用一个复杂的对象(多个值,但一个单一的参数)。希望答案有所帮助。

标签: jquery ajax api asp.net-core


【解决方案1】:

这里基本上有两个问题。一,您不能指定多个参数。直接来自WebAPI documentation

当一个动作从请求体绑定多个参数时,会抛出异常。

但是,我们可以在这里创建一个复杂的对象。如果您还没有阅读过视图模型/DTO,您可能会想阅读一些内容,但为了简单起见,我们可以在这里使用模型。

其次,IFormFile 将绑定而不是字符串的原因与同一文档中推断的数据源有关。 [FromForm] 被推断为 IFormFile 但不是字符串(也不是此处的图像类型)。在此处添加 [FromForm] 告诉操作从表单数据绑定。

    [HttpPost]
    [Route("postmethod")]
    public async Task PostMethod([FromForm]Image image)

如果你想制作一个表单来提交给这个 api 的例子:
HTML(必须指定编码类型):

@model .../Image
<form method="post" enctype="multipart/form-data" id="imageForm">
    @Html.Editorfor(m => m.Code)
    @Html.EditorFor(m => m.File)
    <input type="submit" value="submit"/>
</form>

jQuery:

    $("#imageForm").submit(function(e) {
        e.preventDefault();
        $.ajax({
            type: "post",
            data: new FormData(this),
            processData: false,
            contentType: false,
            url: "api/postmethod",
            success: function (data, response, jqXHR) {
                alert("Success.");
            },
            error: function (jqXHR, response, errorThrown) {
                alert("Error.")
            }
        });
    })

这只是假设您需要该表单,再次记住这不适用于 JSON。你可以在类似的herehere 阅读更多关于这个问题的信息:

【讨论】:

  • 太棒了,你是 100% 正确的。我之前已经通读过这些文件,但我不确定我是否注意到了这方面的内容。一旦我创建了一个具有所需属性的类并将其用作参数,一切都会完美运行!非常感谢! :)
猜你喜欢
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-06-08
  • 2016-07-02
  • 2017-07-10
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多