ASP.NET MVC:从控制器返回CDN图像

时间:2012-02-06 17:26:26

标签: asp.net-mvc image cdn

我知道如何从MVC控制器返回图像,但是想知道从MVC控制器返回CDN中的图像是否会破坏使用CDN进行图像的目的。将使用以下代码导致托管从CDN下载的Web应用程序的Web服务器,然后将其提供给用户从Web服务器下载?图像是否已下载两次,一次是从CDN到网络服务器,然后是网络服务器到用户?如果这样比直接在网络服务器上托管图像更糟糕?或者图像是否只下载一次,直接从CDN下载到最终用户?

如何从MVC控制器返回图像并同时利用CDN?

    public ActionResult Thumb(int id)
    {
        //process 
        var file = Server.MapPath(" path to image in the CDN ");
        //do your stuff
        return File(file, "image/jpg", Path.GetFileName(file));
    }

6 个答案:

答案 0 :(得分:8)

在您的控制器操作中,您需要执行HTTP请求以从远程服务器获取映像:

public ActionResult Thumb(int id)
{
    using (var client = new WebClient())
    {
        byte[] image = client.DownloadData("http://cdn.foo.com/myimage.jpg");
        return File(image, "image/jpg");
    }
}

然后:

<img src="@Url.Action("Thumb")" alt="" />

显然现在图像被下载了两次。一旦从CDN进入控制器,一次从客户端进入。这完全违背了此控制器操作的目的,您可以直接引用CDN中的图像:

<img src="http://cdn.foo.com/myimage.jpg" alt="" />

这显然假设客户端可以访问CDN。

当然,如果您的控制器操作不仅仅是从CDN获取图像并将其流式传输到客户端,例如从CDN获取图像并调整其大小,那么您绝对应该采用第一种方法。

答案 1 :(得分:1)

Server.MapPath用于映射图像的物理路径,它不会对CDN图像执行任何操作,因为它在物理路径上不存在于本地。不,您不想返回文件。

您的HTML只会在<img>标记中引用CDN图像。即

<img src="http://mycdn.com/image" />

答案 2 :(得分:1)

不要从控制器返回实际图像。这更糟糕,因为你下载了两次(CDN - &gt;服务器 - &gt;客户端)。您根本不需要Thumb操作。

如果您需要在控制器中生成CDN上文件的链接,那么只需将属性添加到视图的CDN链接模型中,并将其设置在控制器中。

在控制器中创建链接:

public ActionController SomeAction(int id){
   var model = new SomeActionViewModel();

   model.CDNLink = // do some stuff to generate CDN Link and set them on the model;
   return View(model);
}

然后最终在你的视图中设置它

<img src="@Model.CDNLink" alt=""/>

答案 3 :(得分:1)

我使用URL Rewrite module 2.0 outboundRules。 更改响应html Img(图像),链接(css),脚本(js)标签url。

URL Rewrite Module 2.0 Configuration Reference : URL Rewrite Module 2 : URL Rewrite Module : The Official Microsoft IIS Site

当前回复

...
<img src="/images/photo1.jpg" />
<img src="/images/photo2.jpg" />
...

设置web.config urlrewrite配置。

<rewrite>
    <outboundRules>
        <rule name="cdn" preCondition="html" enabled="true">
            <match filterByTags="Img, Link, Script" 
                        pattern="^/(images|csc|js)/(.*)" />
            <action type="Rewrite" value="//cdn.local/{R:1}/{R:2}" />
        </rule>
        <preConditions>
            <preCondition name="html">
                <add input="{RESPONSE_CONTENT_TYPE}" pattern="text/html" />
            </preCondition>
        </preConditions>
    </outboundRules>
</rewrite>

重写回复

...
<img src="//cdn.local/images/photo1.jpg" />
<img src="//cdn.local/images/photo2.jpg" />
...

希望得到这个帮助。

答案 4 :(得分:1)

CDN配置可能有所不同,但最常见的设置是CDN服务器将充当服务器的大型分布式代理(“原始服务器”)。

CDN并不关心您如何提供内容。您可以告诉它按URL,内容类型或其他因素代理内容。

所以你的情况,假设内容一旦从控制器发送,不会改变,可以设置如下:

  1. 请求CDN服务器
  2. CDN服务器请求原始服务器上的控制器方法
  3. 控制器方法生成内容
  4. CDN为后续请求缓存内容
  5. CDN返回内容
  6. 通过网址对相同内容的后续请求将从CDN
  7. 返回

    返回静态内容时,最重要的因素是您使用的URL结构。

    CDN确实(可以)关注缓存和过期方面的响应标头,但如果您可以正确地精确URL以通过URL提供唯一内容(例如,解决版本问题),则最好避免这种情况。 p>

    如果您尝试保护内容,CDN也可以这样做,但通常需要特定于CDN的技术。

答案 5 :(得分:1)

假设您需要先进行一些计算以找出资源,例如根据某些ID进行查找,以解析CDN网址。您绝对不应该使用Web客户端并将图像下载到字节数组。如果你必须下载文件,它本质上变成一个易变的资源,你需要决定如何处理它,使用断路器,可能没有缓存,你需要缓冲它,以便它不会使用太多记忆。

在这种情况下,根据用例,您最好解析网址并使用重定向301/302。

public ActionResult Thumb(int id)
{
    //resolve url
    var file = " path to image in the CDN ";
    //redirect permanent
    return RedirectPermanent(file);
    //OR redirect 
    return Redirect(file);
}