【问题标题】:Render database image from MVC Controller Action从 MVC 控制器操作渲染数据库图像
【发布时间】:2016-03-14 11:16:45
【问题描述】:

我有一个邮寄活动,它会生成定期发送给客户的 HTML 电子邮件。

最近我更改了系统,允许最终用户配置邮件中的某些图像元素,而不是静态配置。这些图像使用 GUID Id 存储在数据库中,并通过 Controller Action 加载,如下所示:

[HttpGet]
[OutputCache(Duration = 3600, Location = OutputCacheLocation.Client, VaryByParam = "id")]
public virtual ActionResult Image(Guid id)
{
   FileItem picture = FileService.GetItem(id);
   return picture != null ? File(picture.FileData, picture.ContentType) : null;
}

如果电子邮件无法在电子邮件客户端中正确呈现,则会有一个链接可以在浏览器中查看相同的邮件截图。

在浏览器中,所有图像都可以正确加载和显示,但是我的问题是在电子邮件客户端(在本例中为 Outlook 2013 和 Outlook 2010)中,上述方法引用的图像不会加载,仅显示静态图像。

例如,加载良好的图像元素是静态文件,例如:

<img src="http://www.foo.com/es/spacer6.gif" width="1" height="8" border="0" alt="" />

无法正常加载的元素是这样的:

<img src="http://www.foo.com/Packages/Image/0c6d126d-8f62-4e28-9963-7377e73c0482" style="border-style:solid;border-bottom-width:1;border-right-width:1;border-top-width:1;border-left-width:1;border-color:#333;" alt="..." />

所以两者都来自同一个域,只有一个是静态的,一个是通过上面的控制器操作加载的。我猜 Outlook 客户端不喜欢这是指向外部“资源”的链接这一事实,因为它不知道这是仅基于 URL 的图像。

是否可以将我的控制器操作更改为“欺骗” Outlook,使其认为这只是一个静态图像 URL,或者是否有更好的方法来做到这一点。

【问题讨论】:

  • 无论是从静态文件提供内容还是从代码生成,用户代理都没有区别。用户代理不知道您的后端是如何实现的。在两者之间放置一个 HTTP 调试代理(如 Fiddler)并检查差异。 也许 Outlook 很挑剔,因为后一个 URI 没有图像类型扩展,您可以尝试添加“.png”(或相应图像类型的正确扩展名)。
  • @CodeCaster 同意,我曾考虑将控制器方法更改为包含图像类型扩展名的字符串。我的另一个想法是通过将图像存储在 Azure 文件存储而不是数据库中来实现文件存储的现代化(就像我在系统的其他区域中所做的那样),这样我就可以使用 URL 直接将它们提供给存储位置。
  • @CodeCaster,我更改了将图像存储到 Azure 文件存储的机制,现在有了指向真实文件的链接,一切正常。

标签: c# html asp.net-mvc-4 email outlook


【解决方案1】:

首先,确保 picture.ContentType 包含它应该包含的内容(例如,如果图像是 PNG,则为“image/png”)。

否则 Outlook 可能依赖于“正确”的扩展。要找出您可以为您的 guid-URL 添加适当的扩展,然后使用它:

public virtual ActionResult Image(string id)
{
    string s = id.Substring(0, id.IndexOf(".")); // a "." is now required
    Guid guid = Guid.Parse(s);
    FileItem picture = FileService.GetItem(guid);
    return picture != null ? File(picture.FileData, picture.ContentType) : null;
}

【讨论】:

    【解决方案2】:

    我使用下一个代码舞会 puresourcecod.com :

    using System.Drawing;
    using System.Drawing.Imaging;
    using System.IO;
    
    ...
    
    public ActionResult Hello(string text)
    {
        //Create new image
        Image img = new Bitmap(100, 50);
        Graphics g = Graphics.FromImage(img);
    
        //Do some drawing
        Font font = new Font("Arial", 24);
        PointF drawingPoint = new PointF(10, 10);
    
        g.DrawString(text, font, Brushes.Black, drawingPoint);
    
        //Return Image
        MemoryStream ms = new MemoryStream();
        img.Save(ms, ImageFormat.Png);
    
        ms.Position = 0;
    
        return new FileStreamResult(ms, "image/png");
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-29
      • 2015-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      相关资源
      最近更新 更多