首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >通过WebAPI流式传输SqlFileStream

通过WebAPI流式传输SqlFileStream
EN

Stack Overflow用户
提问于 2013-08-08 22:56:34
回答 1查看 1.9K关注 0票数 3

我已经设置了一个支持FILESTREAM的SQL数据库,并尝试通过WebAPI将从数据库中检索到的文件通过SqlFileStream流式传输到浏览器。

由于某些原因,它不工作,但我没有得到适当的错误信息。浏览器只是中止连接,Fiddler也没有显示任何有用的东西,VS中似乎也没有抛出任何错误。

代码语言:javascript
复制
public HttpResponseMessage Get(Guid id)
{
    if(id == null || id == Guid.Empty)
        return Request.CreateResponse(HttpStatusCode.BadRequest);

    try
    {
        FileStreamContext fsc = null;
        Document document = null;
        using(var transaction = new TransactionScope())
        using (var db = new MyEntities())
        {
            try
            {
                fsc = db.Database.SqlQuery<FileStreamContext>("SELECT [File].PathName() AS InternalPath, GET_FILESTREAM_TRANSACTION_CONTEXT() AS TransactionContext FROM Document WHERE id={0}", id).First();
            }
            catch (Exception e)
            {
                Debug.Print(e.ToString());
            }

            document = db.Documents.Where(doc => doc.ID == id).Single();

            var fileStream = new SqlFileStream(fsc.InternalPath, fsc.TransactionContext, FileAccess.Read);

            HttpResponseMessage response = new HttpResponseMessage();
            response.Content = new StreamContent(fileStream);
            //response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
            //response.Content.Headers.ContentDisposition.FileName = document.FileName;
            response.Content.Headers.ContentType = MediaTypeHeaderValue.Parse(document.ContentType);
            return response;
        }
    }
    catch (Exception e)
    {
        return Request.CreateResponse(HttpStatusCode.BadRequest);
    }
}

我怀疑这可能是TransactionScope提前关闭的问题?我不确定为什么我没有收到任何错误消息。

通过WebApi流式传输SqlFileStream的正确方式是什么?

EN

回答 1

Stack Overflow用户

发布于 2013-08-10 01:22:05

不是将内容设置为StreamContent,而是尝试读取控制器中的fileStream,将其放入byte数组中,然后使用ByteArrayContent设置内容

代码语言:javascript
复制
var fileStream = new SqlFileStream(fsc.InternalPath, fsc.TransactionContext, FileAccess.Read);
byte[] fileContent = fileStream.ReadFully(); // you will need to implement ReadFully
HttpResponseMessage response = new HttpResponseMessage();
response.Content = new ByteArrayContent(fileContent);

对于ReadFully实现,使用我使用的here is a link to a Jon Skeet method

我怀疑你关于连接过早关闭的说法是对的。您将DbContext / ObjectContext很好地包装在一个using块中,但我认为这就是问题所在。该上下文在控制器返回HttpResponseMessage之后被处理,但是响应只有权访问流--在传递回浏览器或客户端之前,它仍然需要读取流并将其转换为byte[]。当您使用MemoryStream或类似工具时,这通常会自动发生,因为框架仍然可以访问流以读取其内容。不过,在这种情况下,您需要在读取流之前处理SQL连接。

另一种解决方案可能是对DbContext使用依赖注入,而不是在操作方法中更新它。如果您将IoC容器设置为自动处理HTTP请求末尾的上下文,那么当框架将StreamContent转换为byte[]并通过网络将其推送出去时,它应该仍然可用(未处理)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18129311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档