从MVC控制器将图像渲染到屏幕

时间:2011-03-02 19:28:58

标签: image asp.net-mvc-2

我在数据库中有图像,我想返回图像以便从动作中查看。这是我的行动。

public FileContentResult Index(ItemImageRequest request)
{
    var result = queueService.GetItemImage(request);

    if (result.TotalResults == 0)
        return File(new byte[0], "image/jpeg");

    var image = result.FirstResult;

    return File(image.Image, "image/tif");
}

我也试过这段代码

public FileStreamResult Index(ItemImageRequest request)
{
    //retrieval omitted

    var image = result.FirstResult;

    System.IO.Stream stream = new System.IO.MemoryStream(image.Image);

    return new FileStreamResult(stream, "image/tif");
}

当我在浏览器中执行操作时,它会提示我下载。我不希望它下载,我希望它在浏览器中显示。我该如何做到这一点?

3 个答案:

答案 0 :(得分:8)

如果你使用return Controller.File(filename, ...),你将返回一个FilePathResult,这可能不是你想要的 - 我假设你的样本中的'image'是一个图像文件名('var'的情况)没有帮助任何人...)

如果您使用其他File重载之一,或直接使用FileContentResult或FileStreamResult,您将获得所需的效果。

您不需要创建自定义的ActionResult类(当然,它可能因其他原因而有用。)

然而,刚刚写完所有这些,我意识到你的问题是TIFF不是一种文件格式,浏览器总是可以(永远?)在内部显示,这可能就是为什么它们会提示你下载。

您需要将其重新渲染为PNG或服务器上的某些内容才能在浏览器中显示。

答案 1 :(得分:5)

File ActionResult向HTTP标头添加一行,如下所示:

Content-disposition: attachment; filename=foo

这将导致浏览器尝试下载该文件。这就是指定文件名的重载原因。

您可以创建自己的ActionResult来进行下载,并省略Content-disposition。

如果你想复制和粘贴,我在codeplex上有一个代码:ImageResult.cs

答案 2 :(得分:1)

根据要求,这是我的解决方案。

这是ImageResult类,从John

复制和修改
public class ImageResult : ActionResult
{
    public ImageResult()
    {
    }

    public byte[] ImageData
    {
        get;
        set;
    }

    public MemoryStream ImageStream
    {
        get;
        set;
    }

    public string MimeType
    {
        get;
        set;
    }

    public HttpCacheability Cacheability
    {
        get;
        set;
    }

    public string ETag
    {
        get;
        set;
    }

    public DateTime? Expires
    {
        get;
        set;
    }

    public override void ExecuteResult(ControllerContext context)
    {
        if (this.ImageData == null && ImageStream == null)
        {
            throw new ArgumentNullException("ImageData or ImageStream");
        }

        if (string.IsNullOrEmpty(this.MimeType))
        {
            throw new ArgumentNullException("MimeType");
        }

        context.HttpContext.Response.ContentType = this.MimeType;

        if (!string.IsNullOrEmpty(this.ETag))
        {
            context.HttpContext.Response.Cache.SetETag(this.ETag);
        }

        if (this.Expires.HasValue)
        {
            context.HttpContext.Response.Cache.SetCacheability(this.Cacheability);
            context.HttpContext.Response.Cache.SetExpires(this.Expires.Value);
        }

        if (ImageStream != null)
        {
            ImageData = ImageStream.ToArray();
        } 

        context.HttpContext.Response.OutputStream.Write(this.ImageData, 0, this.ImageData.Length);

    }
}

这是我的行动,为清晰起见而修改

public ActionResult Index(ItemImageRequest request)
{
    var result = queueService.GetItemImage(request);

    if (result.TotalResults == 0)
        return new EmptyResult();

    ItemImage image = result.FirstResult;

    //image.Image is type byte[]
    MemoryStream tiffStream = new MemoryStream(image.Image);

    MemoryStream pngStream = new MemoryStream();

    System.Drawing.Bitmap.FromStream(tiffStream).Save(pngStream, System.Drawing.Imaging.ImageFormat.Png);

    return new ImageResult()
    {
        ImageStream = pngStream,
        MimeType = "image/png",
        Cacheability = HttpCacheability.NoCache
    };
}

感谢John和Will帮我解决这个问题。