Возврат изображения из действия приводит к ошибке в 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).