0

The goal I'm trying to accomplish is simply requesting an image from an API, and returning it to the client-side in the form of an append method.

NO, I cannot just handle this in client side altogether because of a user/pass requirement for the API.

NO, I cannot use @Url.Action(ImageFromPath) method in the src of the image.

That said, here's my back-end code:

[HttpGet("api/GetImage")]
public ActionResult ImageFromPath()
{
    string URL = "http://user:pass@MYIPADDRESS/cgi-bin/snapshot.cgi?c=1&authbasic=asdf1234";

    var srcImage = Image.FromFile(URL);
    var stream = new MemoryStream();
    srcImage.Save(stream, ImageFormat.Png);
    return File(stream.ToArray(), "image/png");
}

The goal in client-side is:

$http.get('/api/GetImage').then(function (response) {
    $("#imgDiv").append('<img src="data:image/png;base64,' + response.data + '" />');
});

The problem I'm having is on line srcImage = Image.FromFile(URL), with error:

An exception of type 'System.IO.FileNotFoundException' occurred in CoreCompat.System.Drawing.dll but was not handled in user code

If it makes any difference, the call to the API URL itself requires a couple seconds to return the Image.

Can anyone advise the proper way to get this accomplished? Or at least help in getting my current approach working?

EDIT - I've looked at How can I convert image url to system.drawing.image for an answer, but it only provides solutions using WebClient which is not available in ASP.Net Core yet.

LatentDenis
  • 2,839
  • 12
  • 48
  • 99
  • @mjwills I've browsed that question - every answer involves `WebClient` which is not available in ASP.Net Core. – LatentDenis Jul 12 '17 at 14:01
  • Does https://stackoverflow.com/questions/26958829/how-do-i-use-the-new-httpclient-from-windows-web-http-to-download-an-image help? – mjwills Jul 12 '17 at 14:02
  • @mjwills regarding that question - Would you happen to know how to include `Windows.Storage.Streams` and `Windows.Web.Http` in ASP.Net Core? – LatentDenis Jul 12 '17 at 14:11
  • The Core alternative (since .NET 4.5 actually...) is HttpClient. – CodeCaster Jul 12 '17 at 14:31

1 Answers1

1

If you want to read a file from URL, you want to use HttpClient.

FilesController.cs

using System;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;

namespace DemoWebCore.Controllers
{
    [Route("api/[controller]")]
    public class FilesController : Controller
    {
        // GET api/files/sample.png
        [HttpGet("{fileName}")]
        public async Task<string> Get(string fileName)
        {
            using (HttpClient client = new HttpClient())
            {
                HttpResponseMessage response = await client.GetAsync(
                     "https://i.stack.imgur.com/hM8Ah.jpg?s=48&g=1");
                byte[] content = await response.Content.ReadAsByteArrayAsync();
                return "data:image/png;base64," + Convert.ToBase64String(content);
            }
        }
    }
}

Usage

HomeController.cs

using Microsoft.AspNetCore.Mvc;

namespace DemoWebCore.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
} 

View

<img id="sample-img" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script type="text/javascript">
    $(function () {
        var url = "/api/files/sample.png";
        $.get(url, function (data) {
            console.log(data);
            $("#sample-img").attr('src', data);
        });
    })
</script>

What you are originally doing is reading a file from file system. If the file is located inside your wwwroot folder, this answer might help you.

Win
  • 61,100
  • 13
  • 102
  • 181
  • Unfortunately, the response I get from the Get call is just `data:image/png;base64,` nothing trailing it. – LatentDenis Jul 12 '17 at 14:33
  • Please use `https://i.stack.imgur.com/hM8Ah.jpg?s=48&g=1` for initial test. – Win Jul 12 '17 at 14:34
  • Yes, the initial test with that URL works. My API call URL doesn't. Your URL already has a `.jpg` extension in it. Any ideas on how to solve this? – LatentDenis Jul 12 '17 at 14:36
  • If a file's extension is changed, you could just update `image/png` to correct ***MIME Content Type***. For original question, using ***HttpClient*** is the solution. Regarding the image API returning nothing, if you create a new question with that API tag, you might get an answer quick. – Win Jul 12 '17 at 14:44
  • Ok - Your answer helped greatly, will accept - I posted a new question per your recommendation: https://stackoverflow.com/questions/45061263/api-call-using-auth-to-get-image-using-httpclient-not-working – LatentDenis Jul 12 '17 at 14:59
  • Win, I've posted a more-refined problem - maybe you can help? https://stackoverflow.com/questions/45066586/why-does-the-same-asp-net-razor-helper-and-api-call-produce-different-image-outp – LatentDenis Jul 12 '17 at 20:19