ASP.NET MVC控制器可以返回一个图像吗?


Answers

使用MVC的发布版本,我做了以下工作:

[AcceptVerbs(HttpVerbs.Get)]
[OutputCache(CacheProfile = "CustomerImages")]
public FileResult Show(int customerId, string imageName)
{
    var path = string.Concat(ConfigData.ImagesDirectory, customerId, "\\", imageName);
    return new FileStreamResult(new FileStream(path, FileMode.Open), "image/jpeg");
}

我显然在这里有一些关于路径构造的应用程序特定的东西,但FileStreamResult的返回很好很简单。

我对这个动作进行了一些性能测试,针对您对图像的每日调用(绕过控制器),平均值之间的差异仅为3毫秒(控制器平均值为68毫秒,非控制器为65毫秒)。

我尝试了一些在这里回答中提到的其他方法,并且性能受到更大的影响......几个解决方案响应高达非控制器的6倍(其他控制器avg 340ms,非控制器65ms)。

Question

我可以创建一个简单地返回图像资源的控制器吗?

我希望通过一个控制器路由这个逻辑,每当需要如下的URL时:

www.mywebsite.com/resource/image/topbanner

控制器将查找topbanner.png并将该图像直接发送回客户端。

我已经看到了这个例子,你必须创建一个视图 - 我不想使用视图。 我只想用Controller来完成这一切。

这可能吗?




为什么不简单并使用波浪号~操作符?

public FileResult TopBanner() {
  return File("~/Content/images/topbanner.png", "image/png");
}



if (!System.IO.File.Exists(filePath))
    return SomeHelper.EmptyImageResult(); // preventing JSON GET/POST exception
else
    return new FilePathResult(filePath, contentType);

SomeHelper.EmptyImageResult()应该返回FileResult与现有的图像(例如1x1透明)。

如果您将文件存储在本地驱动器上,这是最简单的方法。 如果文件是byte[]stream - 然后使用FileContentResultFileStreamResult作为Dylan建议。




如果您想在返回图像之前修改图像,这可能会有所帮助:

public ActionResult GetModifiedImage()
{
    Image image = Image.FromFile(Path.Combine(Server.MapPath("/Content/images"), "image.png"));

    using (Graphics g = Graphics.FromImage(image))
    {
        // do something with the Graphics (eg. write "Hello World!")
        string text = "Hello World!";

        // Create font and brush.
        Font drawFont = new Font("Arial", 10);
        SolidBrush drawBrush = new SolidBrush(Color.Black);

        // Create point for upper-left corner of drawing.
        PointF stringPoint = new PointF(0, 0);

        g.DrawString(text, drawFont, drawBrush, stringPoint);
    }

    MemoryStream ms = new MemoryStream();

    image.Save(ms, System.Drawing.Imaging.ImageFormat.Png);

    return File(ms.ToArray(), "image/png");
}



您可以使用HttpContext.Response并直接将内容写入它(WriteFile()可能适用于您),然后从Action而不是ActionResult返回ContentResult。

免责声明:我没有尝试过,它基于查看可用的API。 :-)




看看ContentResult。 这会返回一个字符串,但可以用来制作自己的BinaryResult类。




这对我有效。 由于我将图像存储在SQL Server数据库中。

    [HttpGet("/image/{uuid}")]
    public IActionResult GetImageFile(string uuid) {
        ActionResult actionResult = new NotFoundResult();
        var fileImage = _db.ImageFiles.Find(uuid);
        if (fileImage != null) {
            actionResult = new FileContentResult(fileImage.Data,
                fileImage.ContentType);
        }
        return actionResult;
    }

在上面的代码片段中, _db.ImageFiles.Find(uuid)正在db(EF上下文)中搜索图像文件记录。 它返回一个FileImage对象,它只是我为该模型创建的一个自定义类,然后将其用作FileContentResult。

public class FileImage {
   public string Uuid { get; set; }
   public byte[] Data { get; set; }
   public string ContentType { get; set; }
}






Links