Как установить возвращаемые данные изображения как ng-src изображения в AngularJS

На данный момент у меня есть два метода ASP.Net Core: один привязан к вызову API, а другой — к помощнику Razor на стороне клиента.

Они оба находятся в моем HomeController.cs.

API:

Вот вызов API:

[HttpGet("api/GetImage")]
public async Task<ActionResult> ImageFromPath()
{
    RestClient client = new RestClient("http://IPADDRESS/cgi-bin/snapshot.cgi?channel=0");
    RestRequest request = new RestRequest(Method.GET);
    request.AddHeader("cache-control", "no-cache");
    request.AddHeader("authorization", "Basic aYu7GI");
    TaskCompletionSource<IRestResponse> taskCompletion = new TaskCompletionSource<IRestResponse>();

    RestRequestAsyncHandle handle = client.ExecuteAsync(request, r => taskCompletion.SetResult(r));
    RestResponse response = (RestResponse)(await taskCompletion.Task);

    return File(response.RawBytes, "image/png");
}

Бритва:

Вот помощник Razor:

public async Task<ActionResult> ImageFromPath()
{
    RestClient client = new RestClient("http://IPADDRESS/cgi-bin/snapshot.cgi?channel=0");
    RestRequest request = new RestRequest(Method.GET);
    request.AddHeader("cache-control", "no-cache");
    request.AddHeader("authorization", "Basic aYu7GI");
    TaskCompletionSource<IRestResponse> taskCompletion = new TaskCompletionSource<IRestResponse>();

    RestRequestAsyncHandle handle = client.ExecuteAsync(request, r => taskCompletion.SetResult(r));
    RestResponse response = (RestResponse)(await taskCompletion.Task);

    return File(response.RawBytes, "image/png");
}

Как видите, приведенные выше тела методов полностью одинаковы. У одного просто есть аннотация HttpGet.


Тем не менее, в сочетании с обработчиками на стороне клиента они дают разные результаты.

API:

Клиентский обработчик вызова API:

<img ng-src="{{imageSrc}}">

$http.get('/api/GetImage', { headers: { 'Accept': 'image/webp,image/apng,image/*,*/*;q=0.8' } }).then(function (response) {
    $scope.imageSrc = response.data;
});

Бритва:

Клиентский обработчик для помощника Razor:

<img src="@Url.Action("ImageFromPath")" id="img2" />

Вот где результаты показывают:

API:

Вот вызов API preview на вкладке "Сеть":

API-предварительный просмотр

Бритва:

Вот вызов помощника Razor preview на вкладке «Сеть»:

бритва-предварительный просмотр

API:

Вот вызов API headers на вкладке "Сеть":

API-заголовки

Бритва:

Вот вызов помощника Razor headers на вкладке «Сеть»:

бритвенные заголовки

API:


Почему помощник Razor фактически создает/возвращает изображение, а вызов API — нет? Как сделать так, чтобы вызов API возвращал изображение так же, как это делает помощник Razor?


person LatentDenis    schedule 12.07.2017    source источник
comment
Оба метода не могут быть внутри HomeController, так как они оба имеют одинаковую сигнатуру метода. В любом случае, если вы введете http://localhost:xxx/api/GetImage в браузере, он что-нибудь покажет?   -  person Win    schedule 12.07.2017
comment
@Win Да, изображение видно. Я также пошел дальше и попытался перенести один из методов на другой контроллер - такая же разница.   -  person LatentDenis    schedule 12.07.2017
comment
Является ли ваша клиентская сторона AngularJS?   -  person Win    schedule 12.07.2017
comment
@Win AngularJS - да. (Я знаю, что это не одобряется, но также использует jQuery вместе), следовательно, внутренний вызов $(#img1)... в вызове $http.get на стороне клиента   -  person LatentDenis    schedule 12.07.2017


Ответы (2)


Вам нужно несколько вещей. Во-первых, вы не должны обращаться к DOM напрямую внутри Angular Controller.

<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular-animate.js"></script>
<script src="http://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-1.3.2.js"></script>
<div ng-app="app">
    <my-content></my-content>
</div>
<script type="text/javascript">
    angular.module('app', []);

    angular.module('app')
        .component('myContent', {
            template: '<h1>{{$ctrl.title}}</h1><img src="{{$ctrl.imageSrc}}" />',
            controller: function ($http) {
                var self = this;
                self.title = "Title";
                // Just to verify image work
                //self.imageSrc = "https://i.stack.imgur.com/hM8Ah.jpg?s=48&g=1";
                $http.get('/Home/ImageFromPath').then(function (response) {
                    console.log(response.data);
                    self.imageSrc = response.data;
                });
            }
        });
</script>

Во-вторых, вам нужно будет вернуть строку, закодированную на основе 64.

using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using RestSharp;

namespace DemoWebCore.Controllers
{
    public class HomeController : Controller
    {
        public async Task<IActionResult> ImageFromPath()
        {
            RestClient client = new RestClient("https://i.stack.imgur.com/hM8Ah.jpg?s=48&g=1");
            RestRequest request = new RestRequest(Method.GET);
            request.AddHeader("cache-control", "no-cache");
            request.AddHeader("authorization", "Basic aYu7GI");
            TaskCompletionSource<IRestResponse> taskCompletion = new TaskCompletionSource<IRestResponse>();
            RestRequestAsyncHandle handle = client.ExecuteAsync(request, r => taskCompletion.SetResult(r));
            RestResponse response = (RestResponse)await taskCompletion.Task;
            return Ok("data:image/png;base64," + Convert.ToBase64String(response.RawBytes));
        }
    }
}
person Win    schedule 12.07.2017
comment
Вот вопрос: если я просто изменю оператор return на return "data:image/png;base64," + Convert.ToBase64String(response);, я получу ошибку, что response не может преобразовать из RestSharp.RestResponse в byte[] - person LatentDenis; 13.07.2017
comment
Вам нужно будет предоставить массив байтов, чтобы преобразовать строку кодировки base64. - person Win; 13.07.2017
comment
Не могли бы вы показать мне пример, основанный на моем текущем коде? Я не уверен, что ты имеешь в виду. - person LatentDenis; 13.07.2017
comment
Попытка вашего предложения выше дает мне ошибку - Cannot implicitly convert type 'string' to 'Microsoft.AspNetCore.Mvc.ActionResult' - person LatentDenis; 13.07.2017
comment
Вам нужно будет использовать public async Task<string> вместо public async Task<ActionResult>. - person Win; 13.07.2017
comment
Я попробовал это только сейчас - я не получаю строку изображения, ответ от этого метода показывает data:image/png;base64, и все. - person LatentDenis; 13.07.2017
comment
В ASP.Net Core DownloadData выдает ошибку, поскольку RestClient не содержит определения для DownloadData. Можете ли вы пересмотреть свой ответ или удалить его? - person LatentDenis; 13.07.2017
comment
Извините, предыдущий код RestSharp был ASP.NET MVC. Я забыл, что вы используете ASP.NET Core. Я обновил ответ рабочим кодом, который я тестировал. - person Win; 13.07.2017
comment
Я не мог бы любить тебя больше прямо сейчас, Вин, это потрясающе - и это действительно очень мне помогло. - person LatentDenis; 13.07.2017

Для этого исправления я использовал:

Request.CreateResponse(HttpStatusCode.OK, "data:image/png;base64," + Convert.ToBase64String(response.GetBuffer()))
person user14061322    schedule 06.08.2020