MemoryStream в IMG через TempData в MVC3 — есть ли лучший способ?

#c# #asp.net-mvc #asp.net-mvc-3

#c# #asp.net-mvc #asp.net-mvc-3

Вопрос:

Модель содержит, среди прочих свойств, метод, который возвращает MSChart как MemoryStream.

На мой взгляд, я копирую MemoryStream в TempData [«Диаграмма»], а затем использую URL.Action() для вызова действия контроллера для возврата FileContentResult с использованием MemoryStream из TempData.

В модели

 public MemoryStream ViewerChart()
{
    Chart chart = new Chart();
    :
    :
    using (MemoryStream memStream = new MemoryStream())
    {
        chart.SaveImage(memStream, ChartImageFormat.Jpeg);
        return memStream;
    }
}
  

В представлении

 @{
    TempData["Chart"]= Model.ViewerChart();
 }
<img alt="Chart" src="@Url.Action("RenderChart")" />
  

В контроллере

  public ActionResult RenderChart()
 {

   MemoryStream ms = TempData["Chart"] as MemoryStream;
   return File(ms.ToArray(), "image/jpeg");
 }
  

Несмотря на то, что все работает нормально, мне все это кажется немного неприятным, особенно использование TempData

Есть ли лучший способ?

Комментарии:

1. Почему вы не можете сгенерировать диаграмму в действии RenderChart ?

2. @Jan — Это действительно приходило мне в голову изначально, но поскольку модель уже инкапсулирует это поведение, я не думал, что это такая хорошая идея повторить это в контроллере.

3. Как получить экземпляр объекта модели в вашем контроллере? Разве вы не можете просто снова получить объект модели в RenderChart действии и вернуть его ViewerChart свойство там?

4. @Jan — Все это довольно стандартные вещи, контроллер создает новый экземпляр модели, передавая ему идентификатор пользователя в конструкторе, модель отправляется в базу данных и получает данные, контроллер передает модель в представление, и представление отображает необработанные данные, а затем мне нужно сделатьэта неприятная возня с TempData и дополнительным действием контроллера для отображения диаграммы из модели в теге <img> . Я мог бы создать еще один экземпляр модели в действии RenderChart, но это кажется таким же плохим (два обращения к базе данных), как и «взлом» TempData.

Ответ №1:

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

Но я думаю, что это правильный подход к сохранению изображения TempData для уменьшения обходов базы данных и повышения производительности.

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

По крайней TempData мере, кажется правильным хранилищем, потому что значение удаляется из коллекции при его чтении RenderChart действием.

Комментарии:

1. Когда я использую этот метод в представлении с сообщением, Internet Explorer 9 (но не Chrome) решает, что ему нужно вызвать RenderChart дважды, и, конечно, во второй раз временные данные были очищены. Ужасный способ обойти это — сбросить TempData [«Chart»] обратно в MemoryStream, который RenderChart только что извлек из TempData, но это глубоко в области хакерства и, вероятно, ужасно хрупко, поэтому я собираюсь принять удар на повторное чтение данных, чтобы это былоболее надежный.

2. Вы проверили с помощью fiddler, что именно запрашивает Internet Explorer во второй раз?

3. Да — он получает только для IMG (диаграммы визуализации) дважды, а не на всей странице, и только на странице, которая публикует не GET. Кажется, есть известные проблемы с тегами IMG с пустым ‘src’. Два запроса выполняются почти одновременно. Я создам простой проект и посмотрю, смогу ли я его воссоздать, но TempData в любом случае кажется немного хрупким, поскольку все, что может вызвать HTTP-запрос, уничтожит его.