【问题标题】:Posting file with HttpClient to a Web Api使用 HttpClient 将文件发布到 Web Api
【发布时间】:2018-08-10 16:13:39
【问题描述】:

我正在使用 C# 和 .NET Framework 4.7 开发 ASP.NET Web Api 2。

我正在尝试使用 HttpClient 实例将文件上传到 Web api。

我已将此添加到 Web.Config:

<httpRuntime targetFramework="4.7" maxRequestLength="1048576" />

[ ... ]

<location path="ProductionOrderApi">
  <system.web>
    <httpRuntime executionTimeout="120" maxRequestLength="81920" />
  </system.web>
</location>

[ ... ]

<security>
  <requestFiltering>
    <requestLimits maxAllowedContentLength="1073741824" />
  </requestFiltering>
</security>

这是web api方法:

[HttpPost]
[Route("api/ProductionOrder/{productionOrderName}/Processed")]
public HttpResponseMessage UploadProductionOrderProcessed(
    string productionOrderName,
    byte[] jsonData)
{
    HttpResponseMessage response = null;

    try
    {
        Data.ProductionOrder po = repository
            .SearchFor(p => string.Equals(p.Name, productionOrderName) &&
                        p.Phase == (byte)Phase.Processed)
            .FirstOrDefault();

        if (po == null)
            response = Request.CreateResponse(HttpStatusCode.InternalServerError);
        else
        {
            string json = Encoding.ASCII.GetString(jsonData);

            StoredProcedureErrors error = 
                StoredProcedures.LoadProcessedBatch(connectionString, json);

            if (error == StoredProcedureErrors.NoError)
                response = Request.CreateResponse(HttpStatusCode.Created);
            else
            {
                response = Request.CreateResponse(HttpStatusCode.InternalServerError);

                exceptionLogger.LogMessage(
                    this.GetType().Name,
                    System.Reflection.MethodBase.GetCurrentMethod().Name,
                    "Database error: " + error);
            }
        }
    }
    catch (Exception ex)
    {
        exceptionLogger.LogCompleteException(
            this.GetType().Name,
            System.Reflection.MethodBase.GetCurrentMethod().Name,
            ex);

        response = Request.CreateResponse(HttpStatusCode.InternalServerError);
    }

    return response;
}

这是拨打电话的客户:

public bool UploadProcessedBatch(string productionOrderName, byte[] jsonData)
{
    string completeUri = string.Format(UploadProcessedBatchUri, productionOrderName);

    return Post<byte[]>(completeUri, jsonData);
}

protected bool Post<T>(string completeUri, T dataToPost)
{
    if (EqualityComparer<T>.Default.Equals(dataToPost, default(T)))
        throw new ArgumentNullException("dataToPost");

    bool result = false;

    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(_webApiHost);
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpContent content = new StringContent(JsonConvert.SerializeObject(dataToPost), Encoding.UTF8, "application/json");
        Task<HttpResponseMessage> response = client.PostAsync(completeUri, content);
        HttpResponseMessage message = response.Result;

        result = (message.StatusCode == HttpStatusCode.Created);

        LatestStatusCode = message.StatusCode;
        ReasonPhrase = message.ReasonPhrase;
    }

    return result;
}

如果我在没有发布任何 jsonData 的情况下使用 PostMan 拨打电话,它会接收到电话,但是当我使用任何 jsonData 拨打电话时,它不会调用它(我在 Web Api 方法的第一行有一个断点):我收到一个异常,说“已取消任务”,还有其他有用的东西。

我要上传的文件很大(超过 7 MB)。

知道发生了什么吗?

我认为问题在于我如何发送数据。我发现的所有示例都是关于使用 Html 表单发送数据的,但我没有找到任何关于如何使用 HttpClient 发送数据的信息。

【问题讨论】:

  • “它没有调用它” - 但是响应是什么?应该有一些错误响应(404 或其他)。
  • @Evk 我收到一个异常说“已取消任务”,还有其他有用的东西。
  • 这样发送文件效率不高。最好使用多部分内容或在 url 中传递一些参数(如 productionOrderName)并在响应正文中传递文件。

标签: c# post asp.net-web-api


【解决方案1】:

编辑:

因此,从 Web Api 2.1 开始,可以使用 BSON,一种“类 JSON”格式,能够发送二进制格式的数据。在linked 文章中,您甚至可以找到使用HttpClient 的示例。

在引入 BSON 之前,绕过 JSON 限制的一种常见方法是将二进制编码为 base64。

原件:

简而言之,您不能简单地将 byte[] 作为 Json 属性发送。

可能的解决方法是:

  1. 在客户端/服务器端进行 Base64 解析
  2. 到目前为止我还没有意识到的另一种可能性是 BSON。查看官方Docsthis 线程了解更多信息。

也许其他人有一些东西要添加到该列表中。

干杯,

【讨论】:

  • 是的,我认为问题在于我如何发送数据。我发现的所有示例都是关于使用 Html 表单发送数据的,但我还没有找到任何关于如何使用 HttpClient 发送数据的信息。谢谢。
  • 那么研究 BSON 可能对您来说很有趣。正如所指出的,我不知道这一点,现在才开始查找。另一方面,base64 是一种广泛使用的编码,您可以经常使用它而不是“开箱即用”。它易于使用,但开销很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-10
  • 1970-01-01
  • 1970-01-01
  • 2011-09-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多