c# - WebApiCompatShim 无法在 .net 核心中正确处理 ByteRangeStreamContent
问题描述
我们必须根据请求中的指定发送部分文件HttpRange
。在 .Net 核心中,我们可以返回任何继承自的对象,FileResult
并且此类具有用于指定是否必须启用范围处理的属性:
/// <summary>
/// Gets or sets the value that enables range processing for the <see cref="FileResult"/>.
/// </summary>
public bool EnableRangeProcessing { get; set; }
我们可以返回这些对象,框架将自动处理请求的“http range”值。到目前为止好多了。但是,他们有意识地决定在一个请求中不支持多个字节范围,在这种情况下,整个文件内容将作为响应发送。(这里是我关于这个问题的 SO 问题的链接)
在我们的案例中,客户希望在一个请求中发送多个字节范围。
出于这个原因,我有两个选择。要么创建支持单个和多个范围的新动作结果类型。或者使用Microsoft.AspNetCore.Mvc.WebApiCompatShim
由 Microsoft 开发并在 ASP.NET Core MVC 中与 ASP.NET Web API 2 兼容的包,以简化现有 Web API 实现的迁移。
我已经创建了一些自定义类型来支持多个范围,但必须对其进行重构和测试。这就是为什么我认为第二种方法可能与这种情况更相关。
所以,这里有步骤。首先,我安装了那个包。然后添加了对AddWebApiConventions
. 这将HttpResponseMessageOutputFormatter
帮助并提示Json
序列化程序正确地执行序列化魔术。
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().AddWebApiConventions();
}
然后刚刚创建了 new ApiController
,它基于以下内容创建响应ByteRangeStreamContent
:
public class FileController : ApiController
{
[HttpGet]
[HttpHead]
[Route("download")]
public ResponseMessageResult Download(string filePath)
{
var response = Request.CreateResponse(HttpStatusCode.PartialContent);
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read);
response.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, MediaTypeNames.Application.Octet);
return ResponseMessage(response);
}
}
该端点可以在 .Net 中执行单个和多个 http 范围请求。但是,在 .net 核心中,它再次仅支持单字节范围响应。
假设我有这样内容的文件:
ABCDFGHIJKLMNOPQRSYUVWXYZ
在单字节范围请求的情况下,响应为:
curl -H Range:bytes=1-5 http://localhost:55348/File/download?filePath=D:\Request.txt -i
ABCDF
但是,如果有多个字节范围请求,它会奇怪地返回第一个范围的完整内容:
curl -H Range:bytes=1-5,6-8 http://localhost:55348/File/download?filePath=D:\Request.txt -i
--51239b4a-9749-481f-a353-6cad668fb7dc
Content-Type: application/octet-stream
Content-Range: bytes 1-5/25
ABCDFGHIJKLMNOPQRSYUVWXYZ -- As you see full content is returned instead of `ABCDF`
--51239b4a-9749-481f-a353-6cad668fb7dc
Content-Type: application/octet-stream
Content-Range: bytes 6-8/25
无法理解为什么它不能在 .net Core 中适当地创建响应。
解决方案
推荐阅读
- typescript - 为什么 TypeScript 允许一个方法返回一个对象字面量,而不能将相同的值分配给其他地方的返回类型?
- azure-table-storage - Mule 4 中的 Azure 表存储
- python - 创建两个不同序列的单个“排序”生成器的 Pythonic 方法
- firebase - 如何查询此 Firebase 结构?
- mysql - 如果我在安装过程中更改了 MySQL 的默认端口号(3306),会不会有什么问题?
- terraform - “count”和“for_each”元参数是互斥的,只有一个应该用来明确要创建的资源数量
- android - 如何将 IIS Express 开发证书导入 Android App?
- java - 关于 Java 中的多态性的 Private vs final
- python - 查找 0 夹在非零值之间的索引
- javascript - 内容固定时背景滚动