ASP .Net Web API загружает изображения в виде двоичных файлов

Я хочу попытаться использовать веб-API для выполнения остаточного вызова, но я хочу, чтобы ответ был фактическим двоичным изображением, хранящимся в базе данных, а не строкой в ​​кодировке JSON base64. Кто-нибудь получил какие-то указатели на это?

Обновление. Вот что я в итоге реализовал:

 HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
 result.Content = new StreamContent(new MemoryStream(profile.Avatar));
 result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
 result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
 result.Content.Headers.ContentDisposition.FileName = "avatar.png";
 return result;

person spaceagestereo    schedule 08.05.2012    source источник
comment
Я думаю, что в этой статье задан аналогичный вопрос stackoverflow.com/questions/8340247/   -  person Glenn Ferrie    schedule 08.05.2012


Ответы (4)


Вы можете установить содержимое ответа в объект StreamContent:

        var fileStream = new FileStream(path, FileMode.Open);

        var resp = new HttpResponseMessage()
        {
            Content = new StreamContent(fileStream)
        };

        // Find the MIME type
        string mimeType = _extensions[Path.GetExtension(path)];
        resp.Content.Headers.ContentType = new MediaTypeHeaderValue(mimeType);
person Mike Wasson    schedule 08.05.2012
comment
Пометил ваш как ответ, потому что это был прямой ответ на вопрос и он был ближе всего к тому, что мне нужно. Спасибо, что нашли время ответить! - person spaceagestereo; 26.06.2012
comment
Решение о том, как вернуть файл из веб-API, см. в самом конце его собственного ответа на странице stackoverflow.com/a. /14819168/179138 - person Caio Cunha; 17.01.2014

Хотя это было помечено как ответ, это было не совсем то, что я хотел, поэтому я продолжал искать. Теперь, когда я разобрался, вот что у меня есть:

public FileContentResult GetFile(string id)
{
    byte[] fileContents;
    using (MemoryStream memoryStream = new MemoryStream())
    {
        using (Bitmap image = new Bitmap(WebRequest.Create(myURL).GetResponse().GetResponseStream()))
            image.Save(memoryStream, ImageFormat.Jpeg);
        fileContents = memoryStream.ToArray();
    }
    return new FileContentResult(fileContents, "image/jpg");
}

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

using (Bitmap image = new Bitmap(WebRequest.Create(myURL).GetResponse().GetResponseStream()))

С этим:

using (Bitmap image = new Bitmap(myFilePath))

РЕДАКТИРОВАТЬ: Неважно, это для обычного MVC. для веб-API у меня есть это:

public HttpResponseMessage Get(string id)
{
    string fileName = string.Format("{0}.jpg", id);
    if (!FileProvider.Exists(fileName))
        throw new HttpResponseException(HttpStatusCode.NotFound);

    FileStream fileStream = FileProvider.Open(fileName);
    HttpResponseMessage response = new HttpResponseMessage { Content = new StreamContent(fileStream) };
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpg");
    response.Content.Headers.ContentLength = FileProvider.GetLength(fileName);
    return response;
}

Что очень похоже на то, что есть у OP.

person vbullinger    schedule 11.02.2013
comment
В моем случае мне нужна была версия Web API. - person Caio Cunha; 17.01.2014
comment
Как насчет объекта FileStream... кто-нибудь знает, правильно ли метод Dispose() по умолчанию для httpResponseMessage уничтожит поток? Наше сканирование безопасности выделяет это как неустраненную потенциальную утечку ресурсов. - person jessewolfe; 04.05.2016

Я сделал именно это. Вот мой код:

if (!String.IsNullOrWhiteSpace(imageName))
                {
                    var savedFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Path.Combine(uploadPath, imageName));
                    var image = System.Drawing.Image.FromFile(savedFileName);

                    if (ImageFormat.Jpeg.Equals(image.RawFormat))
                    {
                        // JPEG
                        using(var memoryStream = new MemoryStream())
                        {
                            image.Save(memoryStream, ImageFormat.Jpeg);

                            var result = new HttpResponseMessage(HttpStatusCode.OK)
                                {
                                    Content = new ByteArrayContent(memoryStream.ToArray())
                                };

                            result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/jpeg");
                            result.Content.Headers.ContentLength = memoryStream.Length;

                            return result;
                        }
                    }
                    else if (ImageFormat.Png.Equals(image.RawFormat))
                    {
                        // PNG
                        using (var memoryStream = new MemoryStream())
                        {
                            image.Save(memoryStream, ImageFormat.Png);

                            var result = new HttpResponseMessage(HttpStatusCode.OK)
                            {
                                Content = new ByteArrayContent(memoryStream.ToArray())
                            };

                            result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/png");
                            result.Content.Headers.ContentLength = memoryStream.Length;

                            return result;
                        }
                    }
                    else if (ImageFormat.Gif.Equals(image.RawFormat))
                    {
                        // GIF
                        using (var memoryStream = new MemoryStream())
                        {
                            image.Save(memoryStream, ImageFormat.Gif);

                            var result = new HttpResponseMessage(HttpStatusCode.OK)
                            {
                                Content = new ByteArrayContent(memoryStream.ToArray())
                            };

                            result.Content.Headers.ContentType = new MediaTypeHeaderValue("image/gif");
                            result.Content.Headers.ContentLength = memoryStream.Length;

                            return result;
                        }
                    }
                }

А потом на клиенте:

                    var client = new HttpClient();
                    var imageName = product.ImageUrl.Replace("~/Uploads/", "");
                var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory,
                                        Properties.Settings.Default.DeviceMediaPath + "\\" + imageName);

                var response =
                    client.GetAsync(apiUrl + "/Image?apiLoginId=" + apiLoginId + "&authorizationToken=" + authToken +
                                    "&imageName=" + product.ImageUrl.Replace("~/Uploads/","")).Result;

                if (response.IsSuccessStatusCode)
                {
                    var data = response.Content.ReadAsByteArrayAsync().Result;
                    using (var ms = new MemoryStream(data))
                    {
                        using (var fs = File.Create(path))
                        {
                            ms.CopyTo(fs);
                        }
                    }

                    result = true;
                }
                else
                {
                    result = false;
                    break;
                }
person aBetterGamer    schedule 29.05.2013

Эта задача легко решается без использования WebAPI. Я бы реализовал собственный HTTP-обработчик для уникального расширения и возвращал бинарный ответ там. Плюсом является то, что вы также можете изменить заголовки HTTP-ответа и тип контента, поэтому у вас есть полный контроль над тем, что возвращается.

Вы можете разработать шаблон URL-адреса (определяющий, как узнать, какое изображение вернуть на основе его URL-адреса), и сохранить эти URL-адреса в своих ресурсах API. Как только URL-адрес возвращается в ответе API, он может быть напрямую запрошен браузером и достигнет вашего обработчика HTTP, возвращая правильное изображение.

Изображения являются статическим содержимым и имеют собственную роль в HTTP и HTML — их не нужно смешивать с JSON, используемым при работе с API.

person Slavo    schedule 08.05.2012
comment
Я думаю, что OP хочет знать, как это сделать с помощью webapi, а не как избежать webapi. - person EBarr; 09.05.2012
comment
Правильно, я знаю о маршруте обработчика HTTP и рассматривал его, но не хотел, чтобы мой код разделялся таким образом. Спасибо, что нашли время ответить. - person spaceagestereo; 10.05.2012
comment
Ну, мои пять копеек. Мне всегда было проще с обработчиками HTTP. - person Slavo; 10.05.2012
comment
Производительность тоже будет фактором. Не уверен насчет обработчиков и веб-API, но если вы используете Http Module для перезаписи URL-адреса в статический файл в IIS, вы получите преимущества производительности статического обработчика файлов IIS. - person Snixtor; 27.11.2012