【问题标题】:Serving file as part of ASP.NET MVC action is slow作为 ASP.NET MVC 操作的一部分提供文件很慢
【发布时间】:2016-11-24 13:03:15
【问题描述】:

在我的一个 ASP.Net MVC 应用程序中,我有一个生成报告的后端。生成报告后,用户可以通过调用操作的链接下载报告。但是,我觉得提供文件的动作有点慢(4 到 8 秒),相比之下,其他动作是瞬时的。

这是提供服务的代码

// GET: /WS/Report/GetReport
[HttpGet]
public ActionResult GetReport(string fileName)
{
    string path = Path.Combine(_reportGeneratedPath, fileName);
    if (!System.IO.File.Exists(path))
        return XmlMessage.Error("Report does not exist");
     Response.ContentType = MimeMapping.GetMimeMapping(fileName);
     Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName));
     Response.AddHeader("Content-Length", new FileInfo(path).Length.ToString());

    Response.WriteFile(path);
    Response.End();
    return null;
}

PS:出于安全原因,我无法切换到直接文件访问。

【问题讨论】:

标签: asp.net asp.net-mvc file download


【解决方案1】:

System.IO.File.Exists 会很慢,因为它是一个 IO 操作。为了加快您的操作,您可以使用 System.Runtime.Caching 的一部分 MemoryCache 来实现缓存机制。此外,Response.WriteFile 是一个同步操作,如果您切换到异步的 Response.TransmitFile,它可能会提高您的响应时间。这种方法是对您所拥有的东西的一个小的增量改进,您也可以使用流式处理方法,这将涉及对您所拥有的东西进行更多的更改。

一旦您的报告生成完成,您将报告完整路径添加到缓存,然后您可以将您的 Action 方法修改为类似的东西(您可以随时改进您的缓存机制,我这里是简单的实现,更多详细信息请访问https://msdn.microsoft.com/en-us/library/system.runtime.caching.memorycache(v=vs.110).aspx)

// GET: /WS/Report/GetReport
[HttpGet]
public ActionResult GetReport(string fileName)
{

    string path = Path.Combine(_reportGeneratedPath, fileName);
    var reportPathCache = MemoryCache.Default;
    if(!reportPathCache.Contains(path))
    {
      return XmlMessage.Error("Report does not exist");
    }
     Response.ContentType = MimeMapping.GetMimeMapping(fileName);
     Response.AddHeader("Content-Disposition", String.Format("attachment; filename={0}", fileName));
     Response.AddHeader("Content-Length", new FileInfo(path).Length.ToString());

    Response.Buffer = false;
    Response.TransmitFile(path);
    Response.End();
    return null;
}

【讨论】:

    【解决方案2】:

    与从 IHttpModule 下载相比,我已将其剥离为“基本”...将单个文件设置到内存中并从操作中下载它。由于某种原因(可能是 MVC 管道负载),IHttpModule 更快(对于小文件,例如产品列表图像)。我没有在路由中使用正则表达式(这会更慢)。在 IHttpModule 中,我达到的速度与 URL 指向驱动器上的文件相同(当然,如果文件在驱动器上,但不在 URL 指向的驱动器位置)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-08
      • 1970-01-01
      相关资源
      最近更新 更多