更新到存储2.1.0.3后,在MVC中返回Blob流时出现NullReferenceException

时间:2013-11-07 18:47:21

标签: azure azure-storage

我的MVC控制器中有几个Actions通过将blob流传递给FileResult来返回Azure blob。像这样:

    public FileResult DownloadReport(string Id)
    {
        // Look up model
        string fileName = messenger.ReportTitle(Id);

        // Get a reference to the blob
        CloudBlockBlob mainReportBlob = cloudBlobContainer.GetBlockBlobReference(Id);

        // Return as a FileResult
        using (var reportReader = mainReportBlob.OpenRead())
        {
            return File(reportReader , "application/pdf", fileName );
        }
    }

我最近将Azure存储库更新为最新版本,并开始收到以下例外情况:

  

System.NullReferenceException未被用户代码
处理    的HResult = -2147467261
   Message =对象引用未设置为对象的实例    来源= Microsoft.WindowsAzure.Storage
   堆栈跟踪:
        atE:\ projects \ azure-sdk-for-net \ microsoft-azure-api \ Services \ Storage \ Lib \中的Microsoft.WindowsAzure.Storage.Blob.BlobReadStreamBase.ConsumeBuffer(Byte [] buffer,Int32 offset,Int32 count) Common \ Blob \ BlobReadStreamBase.cs:第222行         在Microsoft.WindowsAzure.Storage.Blob.BlobReadStream.Read(Byte [] buffer,Int32 offset,Int32 count)中的e:\ projects \ azure-sdk-for-net \ microsoft-azure-api \ Services \ Storage \ Lib \ DotNetCommon \ Blob \ BlobReadStream.cs:第72行         在System.Web.Mvc.FileStreamResult.WriteFile(HttpResponseBase响应)
        在System.Web.Mvc.FileResult.ExecuteResult(ControllerContext context)
        在System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext,ActionResult actionResult)
        在System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList 1 filters, Int32 filterIndex, ResultExecutingContext preContext, ControllerContext controllerContext, ActionResult actionResult)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(IList
1个过滤器,Int32 filterIndex,ResultExecutingContext preContext,ControllerContext controllerContext,ActionResult actionResult)

错误似乎来自Azure库本身。有什么想法吗?

1 个答案:

答案 0 :(得分:6)

因此,在使用反编译器逐步执行操作后,我发现BlobReadStreamBase.Dispose()方法在读取之前就被调用了。进一步挖掘,似乎从控制器返回File()实际上并没有读取流,而只是将其传递给MVC的其余部分来处理它。

这意味着我的using()块正在关闭Blob流,之后MVC可以在管道中进一步读取它。我将行动改为:

    public FileResult DownloadReport(string Id)
    {
        // Look up model
        string fileName = messenger.ReportTitle(Id);

        // Get a reference to the blob
        CloudBlockBlob mainReportBlob = cloudBlobContainer.GetBlockBlobReference(Id);

        // Return as a FileResult, DON'T place in a using() block or it will be closed early
        var reportReader = mainReportBlob.OpenRead();
        return File(reportReader , "application/pdf", fileName );
    }

这很有效。此外,我在我的反编译器中设置了一个断点,稍后调用了BlobReadStreamBase.Dispose(),所以MVC可能会在管道中进一步清理。

我不确定之前为什么会这样,因为它不应该有。也许是Azure库中修复的错误?