私はアプリケーションがASP.netコアであり、支払いを処理するためにspreedly支払いゲートウェイが統合されています。私のログファイルでは、支払いコントローラが2回実行されることがあります。私は、リクエストが受信された時刻に基づいてIDを生成し、IDは時には1秒だけ離れている場合もあれば、まったく同じ時刻にある場合もあります。これにより、カードが2回しか充電されない場合があります。私はこれを引き起こす可能性があるものを把握しているようだ。続きASP.Netコアアクションコントローラが2回呼び出されることがあります
は私が
を使用していたユーザは、申込書を記入し、支払ボタンをクリックして、私はspreedly
$('#REG').click(function() {
var options = {
company_name: "abcd",
sidebar_top_description: "Fees",
sidebar_bottom_description: "Only Visa and Mastercard accepted",
amount: "@string.Format("{0:c}",Convert.ToDecimal(Model.FeeOutstanding))"
}
document.getElementById('payment').value = 'App'
SpreedlyExpress.init(environmentKey, options);
SpreedlyExpress.openView();
$('#spreedly-modal-overlay').css({ "position": "fixed", "z-index": "9999", "bottom": "0", "top": "0", "right": "0", "left": "0" });
});
これはとしてspreedly支払いフォームが開きますトリガするために、このコードを使用していたコードですユーザーがすべてのカード情報を入力して支払いボタンを押すポップアップ。支払コントローラに実行する
public async Task<IActionResult> Index(DynamicViewModel model)
{
if (ModelState.IsValid)
{
try
{
if (TempData.ContainsKey("PaymentFlag") && !String.IsNullOrEmpty(TempData["PaymentFlag"].ToString()))
{
// Some code logic that calls few async methods
//generate a id based on the time of current request
"APP-" + DateTime.Now.ToString("yyyyMMddHmmss-") + model.UserID;
// ... Other code here
}
私が生成するIDが記録され、私はそれはIDが正確に同じ時間のいずれかを有するかを顧客のために二回走ったログファイル内のいくつかの回があったことがわかります1秒差。私はダブルクリックのシナリオをテストして、ダブルクリックを防ぐためのコードもいくつか入れました。しかし、私はなぜこのようなことが起こるのか理解できないようです。それは頻繁ではありません。 100件の支払いでそのような1件が発生します。
私は重複要求を処理するためのアクション属性を持っています。このコードを入力すると、重複要求の数は停止しましたが、完全には停止しませんでした。まだコントローラが2回呼び出される方法はほとんどありません。
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class NoDuplicateRequestAttribute : ActionFilterAttribute
{
public int DelayRequest = 10;
// The Error Message that will be displayed in case of
// excessive Requests
public string ErrorMessage = "Excessive Request Attempts Detected.";
// This will store the URL to Redirect errors to
public string RedirectURL;
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
// Store our HttpContext (for easier reference and code brevity)
var request = filterContext.HttpContext.Request;
// Store our HttpContext.Cache (for easier reference and code brevity)
var cache = filterContext.HttpContext.RequestServices.GetService<IMemoryCache>();
// Grab the IP Address from the originating Request (example)
var originationInfo = request.HttpContext.Connection.RemoteIpAddress.ToString() ?? request.HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress.ToString();
// Append the User Agent
originationInfo += request.Headers["User-Agent"].ToString();
// Now we just need the target URL Information
var targetInfo = request.HttpContext.Request.GetDisplayUrl() + request.QueryString;
// Generate a hash for your strings (appends each of the bytes of
// the value into a single hashed string
var hashValue = string.Join("", MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(originationInfo + targetInfo)).Select(s => s.ToString("x2")));
string cachedHash;
// Checks if the hashed value is contained in the Cache (indicating a repeat request)
if (cache.TryGetValue(hashValue,out cachedHash))
{
// Adds the Error Message to the Model and Redirect
}
else
{
// Adds an empty object to the cache using the hashValue
// to a key (This sets the expiration that will determine
// if the Request is valid or not)
var opts = new MemoryCacheEntryOptions()
{
SlidingExpiration = TimeSpan.FromSeconds(DelayRequest)
};
cache.Set(hashValue,cachedHash,opts);
}
base.OnActionExecuting(filterContext);
}
あなたのコントローラの 'Index'メソッドは基本的に空です。問題を診断するためにコードが必要です。あなたのコントローラの 'Developer Tools'にある' Network'タブをチェックして、実際に複数のリクエストがコントローラに送られてきたかどうかを確認します。それ以外に、あなたが提供したコードに何か狂っているものは見当たらないので、重複した要求を送信していることがわかります。 – Cameron