wake-up-neo.com

ASP .Net Web API zum Herunterladen von Bildern als Binärdatei

Ich möchte versuchen, die Web-API für einen Rest-Aufruf zu verwenden, aber ich möchte, dass die Antwort das eigentliche binäre Bild ist, das in einer Datenbank gespeichert ist, und nicht eine JSON-Base64-codierte Zeichenfolge. Hat jemand ein paar Hinweise dazu?

Update - Das habe ich letztendlich implementiert:

 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;
30
spaceagestereo

Sie können den Antwortinhalt auf ein StreamContent-Objekt festlegen:

        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);
29
Mike Wasson

Obwohl dies als beantwortet markiert wurde, war es nicht ganz das, was ich wollte, also schaute ich weiter. Nun, da ich es herausgefunden habe, habe ich folgendes:

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");
}

Zugegeben, um ein Bild über eine URL zu erhalten. Wenn Sie nur ein Bild vom Dateiserver ziehen möchten, kann ich mir vorstellen, dass Sie diese Zeile ersetzen:

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

Mit diesem:

using (Bitmap image = new Bitmap(myFilePath))

EDIT: Egal, dies ist für reguläre MVC. Für Web-API habe ich Folgendes:

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;
}

Welches ist ziemlich ähnlich was OP hat.

18
vbullinger

Ich habe genau das gemacht. Hier ist mein Code:

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;
                        }
                    }
                }

Und dann auf den Kunden:

                    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;
                }
1
aBetterGamer

Diese Aufgabe ist sehr einfach ohne mit WebAPI zu lösen. Ich würde einen benutzerdefinierten HTTP-Handler für eine eindeutige Erweiterung implementieren und die binäre Antwort dort zurückgeben. Das Plus ist, dass Sie auch die HTTP-Response-Header und den Inhaltstyp ändern können, sodass Sie die vollständige Kontrolle über die zurückgegebenen Informationen haben.

Sie können ein URL-Muster erstellen (das definiert, wie Sie anhand der URL wissen, welches Bild zurückgegeben werden soll) und diese URLs in Ihren API-Ressourcen behalten. Wenn die URL in der API-Antwort zurückgegeben wird, kann sie direkt vom Browser angefordert werden und erreicht Ihren HTTP-Handler. Dabei wird das richtige Bild zurückgegeben.

Bilder sind statischer Inhalt und haben ihre eigene Rolle in HTTP und HTML. Sie müssen nicht mit dem JSON gemischt werden, das beim Arbeiten mit einer API verwendet wird.

0
Slavo