Связь между методом веб-API и представлением MVC с помощью SignalR - PullRequest
2 голосов
/ 01 мая 2019

У нас есть приложение ASP.NET MVC 5, которое загружает представление MVC: Purchase.cshtml. В этом представлении загружается iframe в DIV для стороннего процессора кредитных карт: пользователь вводит данные своей кредитной карты в iframe и нажимает кнопку «PAY». Когда закончите,

  • Обработчик кредитной карты вызывает метод Web API, api/callback, чтобы сообщить нам, что платеж был успешным в течение нескольких секунд после нажатия пользователем кнопки «PAY». Здесь мы регистрируем платеж в нашей системе и используем объект Progress, чтобы уведомить пользователя о ходе этого процесса.
  • Кроме того, iframe процессора кредитных карт перенаправляет на одну из наших страниц MVC - Receipt.cshtml. Мы используем немного JavaScript, чтобы вырваться из iframe при загрузке страницы. Здесь мы все еще находимся в том же сеансе MVC, потому что мы никогда не покидали наш сайт.

Контроллер веб-API вызывается сторонней компанией, но у него будет имя пользователя, который инициировал вызов (который мы храним в приватном поле _userEmail). В методе api/callback здесь мы используем это для отслеживания прогресса:

var progress = new Progress<IPaymentProgress>();
progress.ProgressChanged += OnPaymentProgressChanged;

И эти обработчики:

private async void OnPaymentProgressChanged(object obj, IPaymentProgress e)
{
    await NotifyClientPaymentProgressChanged(e);
}

private async Task NotifyClientPaymentProgressChanged(IPaymentProgress progress)
{
    var context = Microsoft.AspNet.SignalR
        .GlobalHost.ConnectionManager.GetHubContext<PurchaseHub>(); 
    await context.Clients.User(_userEmail).handlePaymentProgressUpdate(progress);
}

В Receipt.cshtml у нас есть этот JavaScript:

$(function () {
    // If page is in iframe, exit it and display fullscreen.
    if (self !== top) {
        top.location.replace(self.location.href);
    }
    $("#progressModal").modal("show");
    var purchaseHubProxy = $.connection.purchaseHub;

    purchaseHubProxy.client.handlePaymentProgressUpdate = function (progress) {
        console.log(progress);
        $('.progress-bar').css("width", progress.Percentage + "%");
        $("#progressMessage").text(progress.Message);
    };

    // Start the connection to get events
    $.connection.hub.start().done(function () {
        console.log("SignalR connected");
    });
});

Приведенный выше console.log выдает оператор SignalR connected через несколько секунд. Однако мы больше ничего не получаем.

Возможно ли, чтобы метод веб-API, запускаемый сторонним приложением, связывался с нашей страницей MVC через SignalR? Имеем ли мы дело с двумя отключенными сеансами между ними - Web API и MVC - и мы не можем отправить SignalR между ними? Если нет, каков наилучший способ показать прогресс в представлении после запуска метода обработки внешних кредитных карт компанией-веб-API?

Примечание. Мы использовали этот же код для успешного общения через SignalR на страницах MVC. Тем не менее, мы никогда не пытались сделать это от Web API до MVC.

Обновление : найдено решение, позволяющее полностью избежать этой головной боли: сторонний процессор cc-1 сначала вызывает наш метод веб-API , а затем перенаправляет iframe в наш метод MVC для загрузки представления ( это не асинхронный, а синхронизация). Поэтому в веб-API мы напишем в нашу базу данных запись об успешном платеже. Затем в методе MVC мы проверим это; если он есть, мы будем обновлять индикатор выполнения через SignalR, что должно быть очень просто.

...