Возврат изображения из действия приводит к ошибке в FireBug/Chrome Dev. инструменты

У меня есть простая форма, которая загружает изображение в базу данных. Используя действие контроллера, изображение может быть возвращено (я жестко закодирован для использования jpeg для этого кода):

public class ImagesController : Controller
{
    [HttpPost]
    public ActionResult Create(HttpPostedFileBase image)
    {
        var message = new MessageItem();
        message.ImageData = new byte[image.ContentLength];
        image.InputStream.Read(message.ImageData, 0, image.ContentLength);
        this.session.Save(message);
        return this.RedirectToAction("index");
    }

    [HttpGet]
    public FileResult View(int id)
    {
        var message = this.session.Get<MessageItem>(id);
        return this.File(message.ImageData, "image/jpeg");
    }
}

Это отлично работает и прямой просмотр изображения (например, /images/view/1) отображает изображение правильно. Тем не менее, я заметил, что когда включен FireBug, меня приветствует приятная ошибка:

Изображение повреждено или усечено: data: image/jpeg; base64,/f39... (за которым следует представление изображения base64).

Дополнительно в инструментах разработчика Chrome:

Ресурс, интерпретируемый как Документ, но переданный с типом MIME image/jpeg.

Я проверил возвращаемые заголовки. Ниже приведен пример заголовков, отправленных обратно в браузер. Ничто не выглядит обычным (возможно, Cache-Control?):

Cache-Control       private, s-maxage=0
Content-Type        image/jpeg
Server              Microsoft-IIS/7.5
X-AspNetMvc-Version 3.0
X-AspNet-Version    4.0.30319
X-SourceFiles       =?UTF-8?B?(Trimmed...)
X-Powered-By        ASP.NET
Date                Wed, 25 May 2011 23:48:22 GMT
Content-Length      21362

Кроме того, я думал, что упомянул, что я запускаю это на IIS Express (даже тестировал на Cassini с теми же результатами).

Нечетная часть заключается в том, что изображение отображается правильно, но консоли сообщают мне об обратном. В идеале я бы не стал игнорировать эти ошибки. Наконец, чтобы добавить к путанице, когда используется изображение (например, <img src="/images/view/1" />), ошибка не возникает.

РЕДАКТИРОВАТЬ. Это можно полностью воспроизвести без каких-либо из перечисленных действий:

public class ImageController : Controller
{
    public FileResult Test()
    {
        // I know this is directly reading from a file, but the whole purpose is
        // to return a *buffer* of a file and not the *path* to the file.
        // This will throw the error in FireBug.
        var buffer = System.IO.File.ReadAllBytes("PATH_TO_JPEG");
        return this.File(buffer, "image/jpeg");
    }
}

Ответы

Ответ 1

Спасибо всем за помощь. Я знаю, что это будет очень антиклиматическое окончание этой проблемы, но я смог "решить" проблему. Я попытался создать свой код с другого компьютера, используя те же версии браузера /firebug. Как ни странно, ошибок не было. Когда я вернулся на другую машину (очистил весь кеш и даже переустановил браузер /firebug ), он все еще получал ошибку. Что еще более странно, так как Chrome/Firefox теперь показывают ошибку, когда я посещаю другие веб-сайты.

Снова, спасибо всем за все их предложения!

Ответ 2

Вы предполагаете, что тип MIME всегда является изображением /jpeg, и вы не используете тип MIME загруженного изображения. Я видел эти типы MIME, размещенные разными браузерами для загруженных изображений:

  • image/gif
  • image/jpeg
  • изображение /pjpeg
  • image/png
  • изображение/х-PNG
  • изображение /BMP
  • изображение/размолвка

Может быть, image/jpeg не является правильным типом MIME для файла, а инструменты dev дают вам предупреждение.

Ответ 3

Может ли быть, что session.Save/Get усекает jpeg?

Ответ 4

Используйте Fiddler и сохраните этот файл на сервере. Попробуйте выполнить запрос GET непосредственно на изображение. Затем попробуйте GET для метода действия. Сравните заголовки и содержимое fiddler (можно сэкономить и сравнить с пробной версией BeyondCompare). Если они подходят для обоих запросов - ну... это не имеет смысла - в этом случае что-то будет отличаться и, надеюсь, укажет на проблему. Что-то должно быть по-другому - но не видя, что выход фиддлера трудно сказать:)

Ответ 5

Возможно ли, что само изображение повреждено? Если вы сохраните его как файл на своем веб-сайте и напрямую обратитесь к нему, возникает ошибка? Как выглядит этот запрос по сравнению с вашим запросом на действия в Fiddler? Возможно, браузеры пытаются получить тип контента по расширению, вы можете попробовать такой маршрут, чтобы увидеть, есть ли какие-либо изменения:

routes.MapRoute(
    "JpegImages",
    "Images/View/{id}.jpg",
    new { controller = "Images", action = "View" }
);

Еще одна вещь, чтобы проверить. image.InputStream.Read() возвращает целое число, которое является фактическим количеством прочитанных байтов. Может быть, все байты не могут быть прочитаны сразу, можете ли вы записать это и выбросить ошибку, если числа не совпадают?

int bytesRead = image.InputStream.Read(message.ImageData, 0, image.ContentLength);
if (bytesRead != image.ContentLength)
    throw new Exception("Invalid length");

Ответ 6

Интересно, связано ли это с X-SourceFiles. Я делаю то же самое, что и вы с MVC, но я сохраняю свой байтовый массив в базе данных. Единственное отличие, которое я не понимаю в наших заголовках, это X-SourceFiles.

Что-то о том, что X-SourceFiles делает Что делает заголовок X-SourceFiles?, и он говорит о кодировании. Так что, может быть?? Ответчик утверждает, что это происходит только на вашем локальном хосте между вами.

Насколько я понимаю, если вы возвращаете правильный массив байтов, который является jpeg, тогда ваш код должен работать нормально. Это именно то, что я делаю успешно (без заголовка X-SourceFiles).