制作一个返回blob .net核心(EF)的get api - c#

我有一个带有ID和BLOB的表的数据库。
我想要的是获取Blob,并从本质上将其流式传输到客户端,
而不是在内存中检索它。那是因为Blob可能真的很大(100 MB)。

我几乎使用SQLdataReader实现了这一目标。
这样做时,当我发出get请求时,它立即开始下载,并且没有内存开销。这是使用.net core 2.2
但是,当我切换到.net core 3.1时,现在它不起作用,并且内存被100兆字节填满。我也想使用实体框架来达到相同的结果,但是到目前为止,我还没有找到任何好的在线资源。

这是我到目前为止的代码。

[HttpGet]
    public  IEnumerable<Byte[]> GetStreaming()
    {

        var header = Request.Headers["Accept-Encoding"];
        System.Console.WriteLine(header);

        string connectionString = "Data Source=myPc\\SQLEXPRESS;Initial Catalog=dbo;Persist Security Info=True;User ID=sa;Password=admin";

        //----------------------
        SqlConnection connection = new SqlConnection(connectionString);

        connection.Open();

        SqlCommand command = new SqlCommand("exec getBlob", connection);

        SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
        command.Transaction = tran;
        byte[] buffer = new byte[5000000];
        long position = 0;
        long bytesRead = 5000000;
        using (SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess))
        {
            reader.Read();
            reader.GetBytes(0, position, null, 0, 5000000);
            while (bytesRead == 5000000)
            {
                // Get the pointer for file
                bytesRead = reader.GetBytes(0, position, buffer, 0, 5000000);
                position += bytesRead;
                yield return buffer;

                // Create the SqlFileStream

            }

        }

    }

我已经试过像这样

        public  IEnumerable<byte[]> DownloadFile()
    {

        yield return  context.t_noFs.Where(u => u.Id == 1)
            .Select(u => u.dat).
            FirstOrDefault();
    }

尽管这确实返回了一个值,但是它没有达到预期的效果,并且会填满内存。

参考方案

在您的情况下,最佳实践是使用流。

[HttpGet]
public  FileStreamResult GetStreaming()
{
    var header = Request.Headers["Accept-Encoding"];
    System.Console.WriteLine(header);

    string connectionString = "Data Source=myPc\\SQLEXPRESS;Initial Catalog=dbo;Persist Security Info=True;User ID=sa;Password=admin";

    //----------------------
    SqlConnection connection = new SqlConnection(connectionString);

    connection.Open();

    SqlCommand command = new SqlCommand("exec getBlob", connection);

    SqlTransaction tran = connection.BeginTransaction(IsolationLevel.ReadCommitted);
    command.Transaction = tran;
    SqlDataReader reader = command.ExecuteReader(CommandBehavior.SequentialAccess)
    var blobStream = reader.GetStream(0);

    return new FileStreamResult(blobStream, "application/x-binary")
    {
         FileDownloadName = "your file name"
    };
}

ASP.NET Web API 2中AuthorizeAttribute发生了什么变化? - c#

我已经将项目和一组单元测试从ASP.NET Web API升级到ASP.NET Web API 2。我们将自定义DelegatingHandler用于自定义身份验证机制。它将Thread.CurrentPrincipal和HttpContext.Current.User设置为适当的System.Security.Claims.ClaimsPrincipal。…

Json参数转换继承Web API 2 - javascript

我正在使用MS Web API 2使用ajax从我们的网页接收呼叫。然后,我有2个类:Subscriber和externalSubscriber。订户包含非常基本的数据,例如名称和ID。外部订户继承自订户并添加基本数据,例如地址和电子邮件。我有一个api方法来编辑这样定义的订户的数据:public IHttpActionResult PutSubscribe…

如何捆绑.Net Core API + Angular前端 - c#

我有一个面向公众的有角前端,它碰到了.NetCore后端。使用webpack将两个项目捆绑在一起。问题是,我需要启用服务器端渲染,并且Microsoft已弃用/ made UseSpaPrerendering。我确实遵循了这个tutorial,但是它在.net core 3.0 / 3.1中根本无法很好地工作。当我开始工作时,我得到一个FOUC(未渲染内容的…

调用SignalR Hub不适用于Asp.Net Core Web API - c#

我是SignalR的新手。我正在尝试设置一个Asp.Net Core WebAPI,以便其他客户端可以使用SignalR连接到它并获取实时数据。我的Hub类是:public class TimeHub : Hub { public async Task UpdateTime(string message) { await Clients.All.SendAs…

将多个对象从Angular控制器发布到Web API 2 - c#

我能够从我的角度控制器发送原始json对象,该对象在我的Web api方法中反序列化为已知类型。很好,但是我现在需要能够在同一请求中发送其他参数,这些参数可以是json对象或简单类型,例如string或int。我看过诸如this之类的文章,它们准确地描述了我的问题,但是它们是从代码隐藏而不是客户端发送请求的。我试图构造一个json数组并将其发送进去,但收到以…