Render image to the screen from MVC controller

前端 未结 3 1380
生来不讨喜
生来不讨喜 2020-12-16 07:32

I have images in the database and I want to return the image for viewing from an action. Here\'s my action.

public FileContentResult Index(ItemImageRequest          


        
相关标签:
3条回答
  • 2020-12-16 07:52

    The File ActionResult adds a line to the HTTP header like this:

    Content-disposition: attachment; filename=foo
    

    This will cause the browser to attempt to download the file. That's why there is an overload to specify the filename.

    You can create your own ActionResult to do the downloading, and omit the Content-disposition.

    If you want to copy-and-paste, I have the code for one on codeplex: ImageResult.cs

    0 讨论(0)
  • 2020-12-16 07:58

    If you use return Controller.File(filename, ...), you'll return a FilePathResult, which probably isn't what you want - I'm assuming that 'image' in your sample is an image filename (a case where 'var' isn't helping anyone...)

    If you use one of the other File overloads, or use FileContentResult or FileStreamResult directly, you'll get the effect you want.

    You don't need to make a custom ActionResult class (though of course, it might be useful for other reasons.)

    HOWEVER, having just written all this, I've realised that your problem is that TIFF is not a file format which browsers can always (ever?) display internally, which is probably why they're prompting for a download.

    You will need to re-render it to a PNG or something on the server to display in a browser.

    0 讨论(0)
  • 2020-12-16 08:04

    As requested, here is my solution.

    Here is the ImageResult class, copied and modified from 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);
    
        }
    }
    

    Here is my action, modified for clarity

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

    Thanks to John and Will for helping me out with this.

    0 讨论(0)
提交回复
热议问题