【问题标题】:HttpClient MultipartFormDataContent only for key value pairs, replacement of working webrequest codeHttpClient MultipartFormDataContent 仅用于键值对,替换工作 webrequest 代码
【发布时间】:2020-11-03 22:27:46
【问题描述】:

我无法将只有键/值对(无文件)的 MultipartFormDataContent 发布请求发送到特定 API。

我试过了:

  • FormUrlEncodedContent 键值对
  • MultipartFormDataContent.Add(new StringContent(value), "nameofvalue");
  • 查看了示例,唯一可行的解​​决方案是使用 Web 请求。 Web请求是老客户端,我 更喜欢使用优雅 -> HttpClient。

附加代码示例,该示例使用 Web 请求,我无法用 HTTP 客户端替换:

public static class FormUpload
{
    private static readonly Encoding encoding = Encoding.UTF8;
    public static HttpWebResponse MultipartFormDataPost(string postUrl, string userAgent, Dictionary<string, object> postParameters)
    {
        var formDataBoundary = $"----------{Guid.NewGuid():N}";
        var contentType = "multipart/form-data; boundary=" + formDataBoundary;

        var formData = GetMultipartFormData(postParameters, formDataBoundary);

        return PostForm(postUrl, userAgent, contentType, formData);
    }
    private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData)
    {
        var request = WebRequest.Create(postUrl) as HttpWebRequest;

        if (request == null)
        {
            throw new NullReferenceException("request is not a http request");
        }

        request.Method = "POST";
        request.ContentType = contentType;
        request.UserAgent = userAgent;
        request.CookieContainer = new CookieContainer();
        request.ContentLength = formData.Length;

        using var requestStream = request.GetRequestStream())
        requestStream.Write(formData, 0, formData.Length);
        requestStream.Close();

        return request.GetResponse() as HttpWebResponse;
    }

    private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary)
    {
        using var formDataStream = new MemoryStream();
        var needsClrf = false;

        foreach (var param in postParameters)
        {
            // Thanks to feedback from commenters, add a CRLF to allow multiple parameters to be added.
            // Skip it on the first parameter, add it to subsequent parameters.
            if (needsClrf)
                formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n"));

            needsClrf = true;

            var postData = $"--{boundary}\r\nContent-Disposition: form-data; name=\"{param.Key}\"\r\n\r\n{param.Value}";
            formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData));
        }

        // Add the end of the request.  Start with a newline
        var footer = "\r\n--" + boundary + "--\r\n";
        formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer));

        // Dump the Stream into a byte[]
        formDataStream.Position = 0;
        var formData = new byte[formDataStream.Length];
        formDataStream.Read(formData, 0, formData.Length);
        return formData;
    }
}

【问题讨论】:

  • 在邮递员中它只是一个简单的表单数据请求,它很容易工作,我无法在 c# 上重现它。截图示例:i.ibb.co/3RsYqyJ/postman.png

标签: .net .net-core httpclient rest


【解决方案1】:

很遗憾,这是服务器端的问题。 client.DefaultRequestHeaders.Add("User-Agent", "C# App"); 是必须的。

坚持使用 FormUrlEncodedContent 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-16
    相关资源
    最近更新 更多