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

我想通过控制器路由这个逻辑,每当请求如下URL时:

www.mywebsite.com/resource/image/topbanner

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

我见过这样的例子,你必须创建一个视图-我不想使用视图。我想只用控制器来做。

这可能吗?


当前回答

我有两个选择:

1)实现你自己的IViewEngine,设置控制器的ViewEngine属性,你正在使用你的ImageViewEngine在你想要的“image”方法。

2)使用视图:-)。只需改变内容类型等。

其他回答

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

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");
}

使用基本控制器文件方法。

public ActionResult Image(string id)
{
    var dir = Server.MapPath("/Images");
    var path = Path.Combine(dir, id + ".jpg"); //validate the path for security or use other means to generate the path.
    return base.File(path, "image/jpeg");
}

值得一提的是,这似乎相当有效。我做了一个测试,我通过控制器(http://localhost/MyController/Image/MyImage)和直接URL (http://localhost/Images/MyImage.jpg)请求图像,结果是:

MVC:每张照片7.6毫秒 直接:每张照片6.7毫秒

注意:这是一个请求的平均时间。平均值是通过在本地机器上发出数千个请求来计算的,因此总数不应该包括网络延迟或带宽问题。

您可以直接写入响应,但这样它就不可测试了。最好返回一个延迟执行的ActionResult。这是我的可重用StreamResult:

public class StreamResult : ViewResult
{
    public Stream Stream { get; set; }
    public string ContentType { get; set; }
    public string ETag { get; set; }

    public override void ExecuteResult(ControllerContext context)
    {
        context.HttpContext.Response.ContentType = ContentType;
        if (ETag != null) context.HttpContext.Response.AddHeader("ETag", ETag);
        const int size = 4096;
        byte[] bytes = new byte[size];
        int numBytes;
        while ((numBytes = Stream.Read(bytes, 0, size)) > 0)
            context.HttpContext.Response.OutputStream.Write(bytes, 0, numBytes);
    }
}
if (!System.IO.File.Exists(filePath))
    return SomeHelper.EmptyImageResult(); // preventing JSON GET/POST exception
else
    return new FilePathResult(filePath, contentType);

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

这是最简单的方法,如果你有文件存储在本地驱动器。 如果文件是字节[]或流-然后使用FileContentResult或FileStreamResult Dylan建议。

更新:有比我原来的答案更好的选择。这在MVC之外工作得很好,但最好坚持使用返回图像内容的内置方法。见赞成投票的答案。

你当然可以。试试下面这些步骤:

将映像从磁盘加载到字节数组中 缓存图像,如果您希望对图像有更多的请求,并且不需要磁盘I/O(我的示例在下面没有缓存它) 通过响应改变mime类型。ContentType 响应。写出图像字节数组

下面是一些示例代码:

string pathToFile = @"C:\Documents and Settings\some_path.jpg";
byte[] imageData = File.ReadAllBytes(pathToFile);
Response.ContentType = "image/jpg";
Response.BinaryWrite(imageData);

希望有帮助!