我尝试制作一个简单的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。
我想念什么?
答案 0 :(得分:5)
响应的内容不应是HttpResponseMessage
的JSON表示形式。
Asp.net核心Web API正在像普通模型对象一样读取HttpResponseMessage
类并将其序列化为JSON。
重构服务器端代码以在控制器中使用建议的语法
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);
}