5

次のリクエストを投稿する必要があります。

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--

requests次のようにPythonライブラリを使用すると、これを非常に簡単に実行できます。

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ライブラリで同じことを行う方法はありますか?

文書化された方法に関する私の問題は、Content-Typeキーと値のペアごとにヘッダーが挿入さfilename*=utf-8''れ、ファイルデータのヘッダーが挿入されることです。ただし、リクエストを送信しようとしているサーバーはこれをサポートしていません。また、ヘッダーの値nameと値を二重引用符で囲んでいることに注意してください。filename

編集:以下は、投稿リクエストを行うために使用したコードです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;
        }
    }
}
4

1 に答える 1

4

仕様(2011 年 6 月付け)によると、互換性を最大限に高めるには、 と の両方filenameを送信することをお勧めします。filename*

この仕様より前の多くのユーザー エージェント実装は、「filename*」パラメーターを理解していません。したがって、「ファイル名」と「ファイル名*」の両方が単一のヘッダーフィールド値に存在する場合、受信者は「ファイル名*」を選択して「ファイル名」を無視する必要があります。このように、送信者は、より表現力豊かな「filename*」パラメーターと「filename」パラメーターの両方を従来の受信者のフォールバックとして送信することにより、特定のユーザー エージェントを特殊なケースで処理することを回避できます。

filename*実際に呼び出しが失敗する原因となっている場合は、サーバーが HTTP 仕様に準拠していることに実際の問題があります。nameまた、 andを引用符で囲むfilenameことは非常に標準的ではありません。

とはいえ、Flurl のショートカットは 90% のケースをカバーしますが、基になる HttpClient API をいつでも使用して、このような異常なケースをカバーできます。Content-Dispositionこの場合、これらのヘッダーを処理できるように、コンテンツを手動で構築する必要があると思います。

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 で使用できます。

var response = await "http://target-host.com"....PostAsync(mpc);
于 2016-08-17T14:06:26.363 に答える