Каковы сценарии сбоя для простой записи изображения в OutputStream типа EmptyResult? - PullRequest
0 голосов
/ 04 марта 2010

Я собрал следующий метод, который вызывает мой репозиторий для получения изображения (возвращается как Linq.Binary).Затем он записывает байтовый массив в OutputStream и устанавливает тип содержимого:

    public EmptyResult GetImage(int id)
    {
        Byte[] imageBytes = _repository.GetImage(id).ToArray();

        Response.OutputStream.Write( imageBytes, 0, imageBytes.Length);
        Response.ContentType = "image/png";

        return new EmptyResult();
    }

Это один из тех случаев, когда я писал блок кода, он работал с первой попытки (всегда страшно), а теперь яЯ пытаюсь продумать, где он сломается.

Мои требования просто вернуть изображение, которое я получаю из базы данных, без текста.

То, что я делаю выше, позволяет мне избежать использования преобразования в растровое изображение (или другой тип изображения), мне не нужно ссылаться на System.Drawing, мне не нужно писатьпользовательский ActionResult, и мне не нужно беспокоиться об утилизации ресурсов.

Мне нужно немного подумать, но я думаю, что это также открывает путь к использованию MVC OutputCache без особых проблем.

Я вижу людей, пишущих собственные ActionResults, и пытаюсь выяснить выгоду.Я имею в виду, я понимаю дополнительную гибкость и способность обрабатывать несколько типов, но одно решение, которое я нашел, - это Binary.ToArray (), преобразованный в растровое изображение и созданный обработчик ashx для возврата изображения.Нужно ли что-нибудь из этого?

Разве это плохо для записи в выходной поток при возврате EmptyResult?

Во всех современных браузерах приведенный выше код позволяет мне отображать изображение с простым:

 <img id="display-image" 
      src="<%= Url.Action("GetImage", new { id = Model.ImageID }) %>" />

Так их недостатки в этом подходе?

Спасибо за мысли / комментарии, друзья.

Приветствия, -james

1 Ответ

1 голос
/ 04 марта 2010

Это плохая форма записи в выходной поток при возврате EmptyResult?

Да, но есть множество более подходящих типов результатов, таких как FileContentResult и FileStreamResult .

Многие люди пишут собственные ActionResults, потому что:

  • Они начали с ранней версии MVC, в которой их не было, или
  • У них очень специфические потребности, не удовлетворяемые встроенными типами
  • Им не нужно помнить, чтобы каждый раз правильно устанавливать mime-type, поэтому они встраивают тип для определенного типа mime (например, встроенный JavaScriptResult).
  • Запись в Response затрудняет проверку контроллеров. Вместо этого вы можете написать в ActionResult.ExecuteResult и иметь тестируемый контроллер.

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

Например, что-то вроде:

public class PngResult : ActionResult {

    public Byte[] Data {
        get;
        set;
    }

    public override void ExecuteResult(ControllerContext context) {
        if (context == null) {
            throw new ArgumentNullException("context");
        }

        if (Data == null)
        {
            throw new InvalidOperationException("Data is null.");
        }

        HttpResponseBase response = context.HttpContext.Response;
        response.ContentType = "image/png";

        response.OutputStream.Write(Data);
    }

    public PngResult(Byte[] data) 
    {
        if (data == null) {
            throw new ArgumentNullException("data");
        }
        this.Data = data;
    }
}

Обновление: Если подумать, возможно, вам следует указать подтип FileContentResult вместо ActionResult, и у вас будет еще меньше кода для записи. Но вы поняли.

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