找不到文件时处理FileContentResult

问题描述 投票:0回答:3

我有一个控制器操作,它根据容器引用名称(即 blob 中文件的完整路径名)从 azure blob 下载文件。代码看起来像这样:

public FileContentResult GetDocument(String pathName)
{
    try
    {
        Byte[] buffer = BlobStorage.DownloadFile(pathName);
        FileContentResult result = new FileContentResult(buffer, "PDF");
        String[] folders = pathName.Split(new char[] { '\\' }, StringSplitOptions.RemoveEmptyEntries);
        // get the last one as actual "file name" based on some convention
        result.FileDownloadName = folders[folders.Length - 1];

        return result;
    }
    catch (Exception ex)
    {
        // log error
    }
    // how to handle if file is not found?
    return new FileContentResult(new byte[] { }, "PDF");
}

BlobStorage
类是我的帮助类,用于从 blob 下载流。

我的问题在代码注释中陈述:当找不到文件/流时,我应该如何处理场景?目前,我正在传递一个空的 PDF 文件,我觉得这不是最好的方法。

c# asp.net-mvc-2 azure-blob-storage filecontentresult
3个回答
22
投票

处理 Web 应用程序中未找到的正确方法是向客户端返回 404 HTTP 状态代码,在 ASP.NET MVC 术语中,这会转换为从控制器操作返回 HttpNotFoundResult

return new HttpNotFoundResult();

啊,哎呀,没注意到你还在 ASP.NET MVC 2。你可以自己实现它,因为

HttpNotFoundResult
仅在 ASP.NET MVC 3 中引入:

public class HttpNotFoundResult : ActionResult
{
    public override void ExecuteResult(ControllerContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }
        context.HttpContext.Response.StatusCode = 404;
    }
}

6
投票

在 ASP.NET Core 中,使用
NotFound()

您的控制器必须继承

Controller
并且该方法必须返回
ActionResult

示例:

public ActionResult GetFile(string path)
{
    if (!File.Exists(path))
    {
        return NotFound();
    }
    
    try
    {
        return new FileContentResult(File.ReadAllBytes(path), "application/octet-stream");
    }
    catch (FileNotFoundException)
    {
        return NotFound();
    }
}

注意:上面的代码并不处理所有文件操作错误的情况,如路径中的无效字符或文件不可用(因为它超出了当前答案的范围)和正确的响应(例如由于权限或其他原因而限制文件访问) )


0
投票

使用 ASP.NET Core 中的 CQRS 模式,可以返回 NoContentResult。

public override async Task<ActionResult> Handle(GetProfileImageQuery request, CancellationToken cancellationToken)
{
    var item = await _mediaProfileImageRepository.GetByUserIdAsNoTracking(request.UserId, cancellationToken);
    if (item is null)
    {
        return new NoContentResult();
    }
    var fileContents = await File.ReadAllBytesAsync(item.FilePath, cancellationToken);

    return new FileContentResult(fileContents, item.ContentType)
    {
        LastModified = item.ModifiedAt,
        FileDownloadName = item.OriginalFileName
    };
}
© www.soinside.com 2019 - 2024. All rights reserved.