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

Ste*_*man 4 azure azure-storage

我在MVC控制器中有几个Action,它们通过将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 );
        }
    }
Run Code Online (Sandbox Code Playgroud)

我最近将我的Azure存储库更新到最新版本并开始收到以下异常:

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

该错误似乎来自Azure库本身.有任何想法吗?

Ste*_*man 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 );
    }
Run Code Online (Sandbox Code Playgroud)

这有效.此外,我在我的反编译器中设置了一个断点,并且稍后调用了BlobReadStreamBase.Dispose(),因此可能MVC正在进一步清理管道中的内容.

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