用Flurl发布`multipart/form-data` [英] Posting `multipart/form-data` with Flurl

查看:535
本文介绍了用Flurl发布`multipart/form-data`的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要发布以下请求:

POST http://target-host.com/some/endpoint HTTP/1.1
Content-Type: multipart/form-data; boundary="2e3956ac-de47-4cad-90df-05199a7c1f53"
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
Content-Length: 6971
Host: target-host.com

--2e3956ac-de47-4cad-90df-05199a7c1f53
Content-Disposition: form-data; name="some-label"

value
--2e3956ac-de47-4cad-90df-05199a7c1f53
Content-Disposition: form-data; name="file"; filename="my-filename.txt"

<file contents>
--2e3956ac-de47-4cad-90df-05199a7c1f53--

我可以使用Python requests库非常容易地做到这一点,如下所示:

I can do this really easily with Python requests library as follows:

import requests

with open("some_file", "rb") as f:
    byte_string = f.read()

requests.post(
    "http://target-host.com/some/endpoint",
    data={"some-label": "value"},
    files={"file": ("my-filename.txt", byte_string)})

有什么办法可以对Flurl.Http库执行同样的操作?

Is there any way to do the same with the Flurl.Http library?

已记录的方式存在的问题是,它将插入<每个键值对的c2>标头,它将为文件数据插入filename*=utf-8''标头.我尝试将请求发布到的服务器不支持此功能.还要注意标题中namefilename值的双引号.

My problem with the documented way of doing it is that it will insert the Content-Type header for each key-value pair and it will insert the filename*=utf-8'' header for the file data. The server I am trying to post the request to, however, does not support this. Also note the double quotes around the name and filename values in the headers.

以下是我用于通过Flurl.Http进行发布请求的代码:

Below is the code I used to make the post request with Flurl.Http:

using System.IO;
using Flurl;
using Flurl.Http;

namespace ConsoleApplication
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var fs = File.OpenRead("some_file");

            var response = "http://target-host.com"
                .AppendPathSegment("some/endpoint")
                .PostMultipartAsync(mp => mp
                    .AddString("some-label", "value")
                    .AddFile("file", fs, "my-filename.txt")
                ).Result;
        }
    }
}

推荐答案

根据规格(日期为2011年6月),建议同时发送filenamefilename*以获得最大兼容性:

According the spec (dated June 2011), sending both filename and filename* is recommended for maximum compatibility:

在此规范之前的许多用户代理实现都没有 了解"filename *"参数.因此,当两个文件名" 和文件名*"出现在单个标头字段值中,收件人 应该选择文件名*"而忽略文件名".这样,发件人可以 通过发送更多的消息,避免使用特殊外壳的特定用户代理 富有表现力的文件名*"参数,而文件名"参数为 后备收件人的回退.

Many user agent implementations predating this specification do not understand the "filename*" parameter. Therefore, when both "filename" and "filename*" are present in a single header field value, recipients SHOULD pick "filename*" and ignore "filename". This way, senders can avoid special-casing specific user agents by sending both the more expressive "filename*" parameter, and the "filename" parameter as fallback for legacy recipients.

如果filename*实际上是导致对 fail 的调用,则服务器遵循HTTP规范确实存在问题.另外,将namefilename用引号引起来是非常不规范的.

If filename* is actually causing the call to fail, there's a real problem with the server adhering to the HTTP spec. Also, enclosing name and filename in quotes is very non-standard.

也就是说,Flurl的快捷方式涵盖了90%的情况,但是您始终可以使用基础的HttpClient API来涵盖这种不寻常的情况.在这种情况下,我认为您需要手动构建内容,以便处理那些Content-Disposition标头:

That said, Flurl's shortcuts cover the 90% cases, but you can always use the underlying HttpClient APIs to cover unusual cases like this one. In this case I think you need to build up the content manually so you can deal with those Content-Disposition headers:

var mpc = new MultipartContent();
var sc = new StringContent("value");
sc.Headers.Add("Content-Disposition", "form-data; name=\"some-label\"");
mpc.Add(sc);
var fc = new StreamContent(fs);
fc.Headers.Add("Content-Disposition", "form-data; name=\"file\"; filename=\"my-filename.txt\"");
mpc.Add(fc);

然后您可以将其与Flurl一起使用,如下所示:

Then you can use it with Flurl like this:

var response = await "http://target-host.com"....PostAsync(mpc);

这篇关于用Flurl发布`multipart/form-data`的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆