Рендеринг изображения на экран из контроллера MVC - PullRequest
4 голосов
/ 02 марта 2011

У меня есть изображения в базе данных, и я хочу вернуть изображение для просмотра из действия. Вот мое действие.

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 ]

8 голосов
/ 02 марта 2011

Если вы используете return Controller.File(filename, ...), вы вернете FilePathResult, что, вероятно, не то, что вы хотите - я предполагаю, что 'image' в вашем образце - это имя файла изображения (случай, когда 'var' isn ' никому не помогаю ...)

Если вы используете одну из других перегрузок файлов или напрямую используете FileContentResult или FileStreamResult, вы получите желаемый эффект.

Вам не нужно создавать собственный класс ActionResult (хотя, конечно, это может быть полезно по другим причинам.)

ОДНАКО, только что написав все это, я понял, что ваша проблема в том, что TIFF не является форматом файла, который браузеры всегда могут (когда-либо?) Отображать внутри, и, вероятно, поэтому они запрашивают скачать.

Вам потребуется повторно отрендерить его в PNG или что-то на сервере для отображения в браузере.

5 голосов
/ 02 марта 2011

File ActionResult добавляет строку в заголовок HTTP следующим образом:

Content-disposition: attachment; filename=foo

Это заставит браузер попытаться загрузить файл.Вот почему существует перегрузка для указания имени файла.

Вы можете создать свой собственный ActionResult, чтобы выполнить загрузку, и опустить расположение контента.

Если вы хотите скопироватьи вставьте, у меня есть код для одного в codeplex: ImageResult.cs

1 голос
/ 03 марта 2011

По запросу, вот мое решение.

Вот класс 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
    };
}

Спасибо Джону и Уиллу за помощь в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...