【发布时间】:2013-11-27 01:43:10
【问题描述】:
我正在尝试使用 .net 4.5 和 web api 将文件从 sql server 异步流式传输到 web 客户端。
我正在使用 SqlDataReader.GetStream() 从数据库中获取流。但是,当 webapi 完成从流中读取时,我不确定如何在处置/关闭 db 连接中进行连接。
有样品吗?
【问题讨论】:
标签: c# asp.net-web-api .net-4.5
我正在尝试使用 .net 4.5 和 web api 将文件从 sql server 异步流式传输到 web 客户端。
我正在使用 SqlDataReader.GetStream() 从数据库中获取流。但是,当 webapi 完成从流中读取时,我不确定如何在处置/关闭 db 连接中进行连接。
有样品吗?
【问题讨论】:
标签: c# asp.net-web-api .net-4.5
您可以在 Web API 中执行以下操作。这里我使用PushStreamContent 连接数据库并检索Sql 流。然后我将这个 sql 流直接复制到响应流中。在 Web API 中,当您使用 PushStreamContent 时,客户端将收到分块传输编码的响应,因为您没有设置响应的内容长度。如果这对您来说没问题,您可以使用以下示例。否则我会尝试看看是否有其他更好的方法来实现这一点。
注意:这是一个基于 PushStreamContent 和 this 在 MSDN 上关于从 sql server 检索二进制数据的文章的快速示例。
[RoutePrefix("api/values")]
public class ValuesController : ApiController
{
private const string connectionString = @"your connection string";
[Route("{id}")]
public HttpResponseMessage GetImage(int id)
{
HttpResponseMessage resp = new HttpResponseMessage();
resp.Content = new PushStreamContent(async (responseStream, content, context) =>
{
await CopyBinaryValueToResponseStream(responseStream, id);
});
return resp;
}
// Application retrieving a large BLOB from SQL Server in .NET 4.5 using the new asynchronous capability
private static async Task CopyBinaryValueToResponseStream(Stream responseStream, int imageId)
{
// PushStreamContent requires the responseStream to be closed
// for signaling it that you have finished writing the response.
using (responseStream)
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
await connection.OpenAsync();
using (SqlCommand command = new SqlCommand("SELECT [bindata] FROM [Streams] WHERE [id]=@id", connection))
{
command.Parameters.AddWithValue("id", imageId);
// The reader needs to be executed with the SequentialAccess behavior to enable network streaming
// Otherwise ReadAsync will buffer the entire BLOB into memory which can cause scalability issues or even OutOfMemoryExceptions
using (SqlDataReader reader = await command.ExecuteReaderAsync(CommandBehavior.SequentialAccess))
{
if (await reader.ReadAsync())
{
if (!(await reader.IsDBNullAsync(0)))
{
using (Stream data = reader.GetStream(0))
{
// Asynchronously copy the stream from the server to the response stream
await data.CopyToAsync(responseStream);
}
}
}
}
}
}
}// close response stream
}
}
【讨论】:
Microsoft.AspNet.WebApi.Core nuget 包?
您可以编写一个包装流,该流从底层流中读取直到耗尽,然后释放所有相关资源(如 SqlConnection)。
我不是 WebAPI 专家,所以可能有更优雅的方式来做这件事。但这在任何情况下都适用于流的标准 WebAPI 支持。
【讨论】: