c# - 如何正确写入从 Web API 接收的文件

标签 c# asp.net-core-webapi

我尝试制作一个简单的 Web API 来从服务器接收文件。

这是服务器部分:

var result = new HttpResponseMessage(HttpStatusCode.OK);
var stream = new FileStream(itemPath, FileMode.Open, FileAccess.Read);
result.Content = new StreamContent(stream);
result.Content.Headers.ContentType = 
      new MediaTypeHeaderValue("application/octet-stream");
result.Content.Headers.ContentDisposition = 
      new ContentDispositionHeaderValue("attachment") { FileName = itemPath };
return result;

客户端部分:

var client = new HttpClient();
var responce = Task.Run(() => client.GetAsync(@"https://localhost:...")).Result;
var bytes = Task.Run(() => responce.Content.ReadAsByteArrayAsync()).Result;
var writer = 
  new BinaryWriter(new FileStream(fileName, FileMode.CreateNew, FileAccess.Write));
writer.Write(bytes);
writer.Close();

以及写入的文件内容:

{"version":{"major":1,"minor":1,"build":-1,"revision":-1,"majorRevision":-1,
"minorRevision":-1},"content":{"headers":[{"key":"Content-Type","value":["application/octet-stream"]},{"key":"Content-Disposition",
"value":["attachment; filename=\"=?utf-8?B?ZDpcTGlicmFyeVBhdGhc0J/QsNGH0LXQutC+XEV4YW1wbGUgR
DVcQ2QxN1xDTElQQlJEXE1haW5Gcm0ucGFz?=\""]}]},"statusCode":200,
"reasonPhrase":"OK","headers":[],"requestMessage":null,"isSuccessStatusCode":true}

我预计此文件将包含来自服务器本身的文件,但不包含描述它的 JSON。

我错过了什么?

最佳答案

响应的内容不应是 HttpResponseMessage 的 JSON 表示形式。

Asp.net Core Web API 像普通模型对象一样读取 HttpResponseMessage 类并将其序列化为 JSON。

重构服务器端代码以在 Controller 中使用建议的语法

public IActionResult MyAction(...) {
    //...
    var stream = new FileStream(itemPath, FileMode.Open, FileAccess.Read);
    return File(stream, "application/octet-stream", "desired file name here");
}

它返回一个IActionResult派生的FileStreamResult

在客户端,尝试避免阻塞调用,例如.Result。还不清楚为什么异步调用在已经可以等待的情况下被包装在 Task.Run 中。

始终保持代码异步

var client = new HttpClient();
var response = await client.GetAsync(@"https://localhost:..."); ;
var bytes = await response.Content.ReadAsByteArrayAsync();
var fileName = response.Content.Headers.ContentDisposition.FileName;
using (var stream = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write)) {
    await stream.WriteAsync(bytes, 0, bytes.Length);
}

响应内容可以作为流读取并直接复制到文件流

var client = new HttpClient();
var response = await client.GetAsync(@"https://localhost:..."); ;
var stream = await response.Content.ReadAsStreamAsync();
var fileName = response.Content.Headers.ContentDisposition.FileName;
using (var fileStream = new FileStream(fileName, FileMode.CreateNew, FileAccess.Write)) {
    await stream.CopyToAsync(fileStream);
}

关于c# - 如何正确写入从 Web API 接收的文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52910714/

相关文章:

c# - 将类对象转换为数据源

azure - 为什么我应该更喜欢 Azure 应用服务而不是 .NET REST Web API?

c# - 使用单个 Entity Framework Core DbContext 管理具有同名表的多个数据库模式

c# - 在将字符串从一种形式传递到另一种形式时调用函数

ajax - 当用户登录到 Web 应用程序时通过 AJAX 访问 .NET Core Web API

c# - JwtSecurityTokenHandler.ValidateToken 抛出生命周期验证失败异常

c# - 使用 Entity Framework Core 数据库优先方法,如何将实体与基础设施层分离?

c# - 无法在 .NET Core for Async 方法中访问 DbContext 的处置对象

c# - 使用 Linq 获取 List<string> 集合中的子字符串

c# - 未指定钱包文件(必须通过/wallet/<filename> uri-path 请求钱包 RPC)。在 C# 中使用 BitcoinLib 备份钱包时出错