ASP.NET (MVC) 服务图像

Posted

技术标签:

【中文标题】ASP.NET (MVC) 服务图像【英文标题】:ASP.NET (MVC) Serving images 【发布时间】:2011-04-07 22:18:19 【问题描述】:

我正在创建一个 MVC 3 应用程序(尽管同样适用于其他技术,例如 ASP.NET 表单)并且只是想知道从代码提供图像而不是使用直接虚拟路径(例如通常)。

我的想法是我将提供文件的常用方法改进为:

    应用安全检查 基于路由值提供文件的标准化方法 返回修改后的图像(如果请求),例如不同的维度(好吧,这只会被谨慎使用,所以不要将它与上面的性能问题联系起来)。 在允许访问资源之前执行业务逻辑

我知道该怎么做,但我不知道我是否应该这样做。

    有哪些性能问题(如果有) 是否发生了一些奇怪的事情,例如?图像仅按顺序加载(也许这就是 html 目前我不确定的方式 - 在这里暴露我的无知)。 你能想到的任何其他东西。

希望这一切都有意义!

谢谢, 丹。

更新

好的 - 让我们具体一点:

使用这种方法在 MVC 3 中使用内存流为所有图像提供服务对性能有何影响?注意:图像 url 将是 GenericFetchImage/image1 (为了简单起见 - 我所有的图像都是 jpegs)。

public FileStreamResult GenericFetchImage(string RouteValueRefToImage)

    // Create a new memory stream object
    MemoryStream ms = new MemoryStream();

    // Go get image from file location
    ms = GetImageAndPutIntoMemoryStream(RouteValueRefToImage);

    // return the output as a file
    return new FileStreamResult(ms, "image/jpeg");
 

我知道此方法有效,因为我正在使用它根据验证码图像的会话值动态生成图像。它非常简洁 - 但我想将这种方法用于所有图像检索。

我想我想在上面的例子中我想知道这是否可以执行,或者是否需要更多处理才能执行,如果可以,需要多少?例如,如果访问者的数量要乘以 1000,那么服务器是否会在图像传递中承担处理负担..

谢谢!

【问题讨论】:

性能和“如果发生奇怪的事情”都完全取决于您构建应用程序的方式......这是非常主观的。 性能完全取决于您的交付方式。您打算如何将图像交付给客户。 嗨,比尔和 womp - 我已经用一个例子更新了我的问题。我想到了性能影响。 IIS 将数据直接从文件流式传输到客户端,因此即使对于许多连接也使用很少的 RAM。如果您每次都将每个文件都缓冲到内存中,那么您将很快耗尽 RAM。 (拨号客户端可能需要几分钟来下载一个小文件,想想tit).. @Levitikon 移动版。将“拨号”替换为“EDGE”或“AT&T 3G”。持久的请求在这里并不是异常,您需要面对它的现实。您不能假装一次只处理一个请求。 【参考方案1】:

之前有人问过一个类似的问题 (Can an ASP.Net MVC controller return an Image?),看起来与直接提供图片相比,性能影响非常小。正如公认的答案所指出的,差异似乎是毫秒级的(在那个测试用例中,大约 13%)。您可以在本地重新运行测试,看看您的硬件有什么不同。

如果您应该使用它的问题的最佳答案是从 answer 到(另一个)类似问题(强调我的):

请注意以下几点:您需要在服务器上重新实现缓存策略,因为 IIS 会为直接请求的静态文件管理该策略。您还需要确保使用响应中包含的正确标头来管理客户端缓存。 最后,问问自己,重新发明一种从服务器提供静态文件的方法是否可以满足您的应用程序的需求。

解决您提供的问题的具体案例:

    应用安全检查

    您已经可以使用IIS 7 integrated pipeline 执行此操作。文档中的相关位:

    允许本机和托管模块提供的服务应用于所有请求,无论处理程序如何。例如,托管表单身份验证可用于所有内容,包括 ASP 页面、CGI 和静态文件

    基于路由值提供文件的标准化方法

    如果我正确阅读了文档,您可以在管道中尽早插入一个模块,以重写传入的 URL 以直接指向静态资源并让 IIS 处理来自那里的请求。 (为了完整起见,还有关于将路线映射到法师的相关问题:How do I route images using ASP.Net MVC routing?)

    使 ASP.NET 组件能够提供以前由于放置在服务器管道中而无法提供的功能。例如,提供请求重写功能的托管模块可以在任何服务器处理之前重写请求,包括身份验证。

    还有一些相当强大的URL rewrite features 或多或少随 IIS 一起提供。

    返回修改后的图像(如果需要),例如不同的维度(好吧,这只会被谨慎使用,所以不要将它与上面的性能问题联系起来)。

    看起来module that does this 已经可用于 IIS。不确定这是否属于通过代码提供图像的范围,但我猜它可能。

    在允许访问资源之前执行业务逻辑

    如果您正在执行业务逻辑来生成所述资源(例如 chart),或者您提到了验证码图像,那么是的,您基本上别无选择,只能这样做。

【讨论】:

我已经用一个具体的例子更新了我的帖子。就像我说的那样,这不是我在挣扎的方式,而是我在质疑的 IF。我不想让我的服务器停机,只是提供图像。 :) 但反应很好。 @Dan B:所以我认为我的答案解决了这个问题,但如果不是,我可以尝试改写一下。第一个链接基本上指向“是否存在速度差异”的相同问题,我相信接受的答案表明存在但很小,大约 1 毫秒。 IF 的另一部分是您可以使用 IIS 完成大部分工作,这可能更灵活(因为更改规则不需要更改代码和重新部署应用程序)并且对更多人来说可能感觉更自然(最少意外原则)。这有没有帮助? 你上面提到的模块不是免费的。我已经摆脱了 URL 重写(因为路由非常好)。你发送的链接太棒了。但两者都没有提到 FileStreamResult 的速度,这是我更新的问题中所述的速度。如果没有其他人有贡献,我将在几天内标记为答案。感谢您的反馈! @Dan B:感谢您的反馈,我重写了部分答案,希望能更好地回答您的问题。是的,我链接的模块不是免费的,但它可能比您开发类似功能的时间便宜(至少对您的雇主而言)。我也会采用“另一种工具是否已经可以做到这一点或更好”的方法。如果答案是肯定的,我会倾向于使用该工具而不是自己动手。这样您就可以从该工具的任何性能改进中受益。

以上是关于ASP.NET (MVC) 服务图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 Asp.Net MVC 创建私人照片库

在 asp.net MVC 中显示保存在数据库中的图像

如何使用 ASP.Net MVC 路由来路由图像?

Asp.net MVC:上传多个图像文件?

在 ASP.NET MVC 中上传图像

文件/图像上传后 ASP.NET 3.0 mvc 应用程序崩溃