我们有一个ASP.NET MVC 5应用程序,该应用程序加载MVC视图:Purchase.cshtml
。该视图将iframe加载到第三方信用卡处理器的DIV中:用户在iframe中输入其信用卡详细信息,然后单击“付款”。完成后,
api/callback
,让我们知道在用户单击“付款”后几秒钟内付款已成功。在这里,我们将付款记录在我们的系统中,并使用Progress
对象向用户通知此过程的进度。Receipt.cshtml
。我们使用一些JavaScript在页面加载时突破iframe。在这里,我们仍处于同一MVC会话中,因为我们从未离开过我们的网站。 Web 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
。但是,我们什么也没有。
由第三方应用触发的Web API方法是否可以通过SignalR与我们的MVC页面进行通信?我们是否正在处理它们之间的两个断开的会话-Web API和MVC-并且我们无法在它们之间发送SignalR?如果没有,那么在外部信用卡处理公司触发Web API方法后,将进度推送到视图的最佳方法是什么?
注意:我们已经使用相同的代码成功通过MVC页面上的SignalR进行通信。但是,我们从未尝试过从Web API到MVC视图。
更新:找到了一种完全避免这种麻烦的解决方案:第3方cc处理器首先调用我们的Web API方法然后将iframe重定向到我们的MVC方法以加载视图(不是异步而是同步)。因此,在Web API中,我们会将一条记录写入数据库,以指示成功付款。然后,在MVC方法中,我们将进行检查;如果有的话,我们将通过SignalR进行进度条更新-应该是小菜一碟。