1

I wanna achieve a simple task, which is to retrieve the binary image, and display it in my html

public class Artwork

{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid artworkID { get; set; }
    public string artworkName { get; set; }
    public string artworkMimeType { get; set; }
    public byte[] artworkMeta { get; set; }
    public string artworkBase64String { get; set; }
}

Gets the artwork from DB

public Artwork GetArtwork(Guid id)
    {
        return _context.Artworks.SingleOrDefault(a => a.artworkID == id);
    }

The API Controller

public IHttpActionResult Get(Guid id)
        {
            if (id == null)
            {
                return BadRequest();
            }
            var artwork = _repository.GetArtwork(id);
            if (artwork == null)
                return NotFound();
            else
                return Ok(artwork);
        }

I've also used this method and it returns the data I want, but I still don't know how to use it to achieve my goal.

[HttpGet]
    public HttpResponseMessage Get(Guid id)
    {
        HttpResponseMessage result = null;
        try
        {
            var artwork = _repository.GetArtwork(id);

            if (artwork == null)
            {
                result = Request.CreateResponse(HttpStatusCode.Gone);
            }
            else
            {
                // sendo file to client
                byte[] bytes = artwork.artworkMeta ;


                result = Request.CreateResponse(HttpStatusCode.OK);
                result.Content = new ByteArrayContent(bytes);
                result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
                result.Content.Headers.ContentDisposition.FileName = artwork.artworkName;
            }

            return result;
        }
        catch (Exception ex)
        {
            return Request.CreateResponse(HttpStatusCode.Gone);
        }
    }

And here's my angular request

$scope.getCity = function (id) {
            $http.get('/api/artwork/' + $RouteParams.id).success(function (response) {
                $scope.artwork= response;
                //I've seen dudes using Blob here, but I'm not sure how that works
            });
        }

My problem is my angular request and my html, how do I display the artwork without doing this:

<img ng-src="data:{{artwork.artworkartworkMimeType}};base64,{{artwork.artworkBase64String}}" class="img-responsive" />

This displays the image, but I don't like how clumsy it looks, and I'm gonna be working with audio files as well, so I need a clean and understandable way. Please help!

2 Answers 2

2

As you said, this can be done by using a blob.

First step is to set the content type to application/octet-stream in the api method

[HttpGet]
public HttpResponseMessage Get(Guid id)
{
    HttpResponseMessage result = null;
    try
    {
        var artwork = _repository.GetArtwork(id);
        if (artwork == null)
        {
            result = Request.CreateResponse(HttpStatusCode.Gone);
        }
        else
        {
            // sendo file to client
            byte[] bytes = artwork.artworkMeta ;
            result = Request.CreateResponse(HttpStatusCode.OK);
            result.Content = new ByteArrayContent(bytes);
            result.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
            result.Content.Headers.ContentDisposition.FileName = artwork.artworkName;
            result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        } 

        return result;
    }
    catch (Exception ex)
    {
        return Request.CreateResponse(HttpStatusCode.Gone);
    }
}

Then add the client request where you create a blob from the response. An url is then created for the blob which will be the source for the img

$scope.fileURL = '';
$http({
    method: 'GET',
    url: '/api/artwork/' + $RouteParams.id,
    responseType: 'arraybuffer',
    headers: {
        'Access-Control-Allow-Origin': '*',
    }
}).success(function (data, status, headers) {
    headers = headers();
    var contentType = headers['content-type'];
    var blob = new Blob([data], { type: contentType });
    //Create a url to the blob 
    $scope.fileURL = window.URL.createObjectURL(blob);

}).error(function (message) {
    console.log(message);
});

Then bind url to the ngSrc

<img ng-src="{{fileURL}}" class="img-responsive" />
Sign up to request clarification or add additional context in comments.

2 Comments

This worked perfectly, and cleaned my code a lot. Thank you so much!!
Great! Np, happy to help :)
0

You could store image in binary format without encoding it to base64. Then it would be simpler to retrive image from DB. In your asp controller:

  [HttpGet]
  public FileResult GetPhoto(int id) {

      return File(_repository.GetArtwork(id).artworkMeta, "image/jpg");

  }

And in angular view:

  <img ng-src="/Home/GetPhoto/2" />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.