WebApiCompatShim无法在.net核心中正确处理ByteRangeStreamContent

时间:2019-11-06 13:33:14

标签: c# asp.net-core curl asp.net-web-api .net-core

我们必须根据请求中指定的HttpRange发送文件的一部分。在.Net core中,我们可以返回从FileResult继承的任何对象,并且此类具有用于指定是否必须启用范围处理的属性:

/// <summary>
/// Gets or sets the value that enables range processing for the <see cref="FileResult"/>.
/// </summary>
public bool EnableRangeProcessing { get; set; }

我们可以返回那些对象,框架将自动处理请求的“ http范围”值。到目前为止更好。但是,他们有意识地决定在一个请求中不支持多个字节范围,在这种情况下,整个文件内容将作为响应发送。 (here是我对此问题的SO问题的链接)

在我们的例子中,客户希望在一个请求中发送多个字节范围。

因此,我有两个选择。创建支持单个范围和多个范围的新操作结果类型。或者使用Microsoft开发的Microsoft.AspNetCore.Mvc.WebApiCompatShim软件包,该软件包在ASP.NET Core MVC中提供与ASP.NET Web API 2的兼容性,以简化现有Web API实现的迁移。

我已经创建了一些自定义类型来支持多个范围,但是必须对其进行重构,测试。 这就是为什么我认为第二种方法与这种情况更为相关。

因此,这是步骤。首先,我安装了该软件包。然后添加对AddWebApiConventions的呼叫。这将连接HttpResponseMessageOutputFormatter来帮助并提示Json序列化程序正确执行其序列化魔术。

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().AddWebApiConventions();
}

然后刚刚创建了新的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中适当地创建响应。

0 个答案:

没有答案