簡體   English   中英

控制器操作被調用兩次,IIS日志沒有顯示

[英]Controller action is getting called twice and IIS logs do not show that

我有奇怪的行為,無法在本地機器上復制,它開始讓我瘋狂。

看起來ASP.NET MVC正在嘗試執行操作,某些超時,它會在沒有任何異常的情況下失敗並通知ajax客戶端,然后嘗試重新運行操作,ajax客戶端獲得響應,但不是來自原始調用。

我有一個控制器動作:

 [ValidateAntiForgeryToken]
 [ClientErrorHandler]
 public virtual ActionResult PlaceOrder(CheckoutDto checkoutDto)
 {
     LoadDataFromDatabase();

     // this may take up to couple minutes
     var orderConfirmationData = PlaceOrderToExternalWebservice();

     SaveConfirmationData(orderConfirmationData);

     return View(Transform(orderConfirmationData))
 }

我用jquery ajax調用它:

$.ajax({
                url: placeOrderActionUrl,
                type: "POST",
                async: true,
                dataType: "html",
                data: $('#checkoutForm').serialize(),                    
                success: function (data) {
                   // show confirmation data                       
                },
                error: function (request, status, error) {
                   // show error message
                }
            });

對於小訂單,它工作正常,但對於大訂單,創建了兩個訂單,理由似乎是處理時間,訂單越大,將其放置到外部Web服務所花費的時間就越多。

我檢查了IIS日志,以確保客戶端腳本沒有兩次調用操作 - 並且IIS日志只顯示對特定操作的一次調用。

外部服務不會失敗,事件日志/ sql日志中沒有記錄異常。

為了確保,ajax客戶端得到的響應不是來自原始調用我已經做了一些鎖定:

 [ValidateAntiForgeryToken]
 [ClientErrorHandler]
 public virtual ActionResult PlaceOrder(CheckoutDto checkoutDto)
 {
     try 
     {
        if (OrderingLockedForCurrentUser()) 
        {
            Log("Locked");
            return View("Already placing order");
        }

        LockOrderingForCurrentUser();

        LoadDataFromDatabase();

        // this may take up to couple minutes
        var orderConfirmationData = PlaceOrderToExternalWebservice();

        SaveConfirmationData(orderConfirmationData);

        return View(Transform(orderConfirmationData))
     }
     finally 
     {
        RemoveOrderingLockForCurrentUser();
     }
 }

而不是返回確認的數據,它返回“已經下訂單”。

我想也許是動作執行超時,但我只是為了清酒而嘗試過

<httpRuntime executionTimeout="600" />

沒有幫助。

任何想法在哪里搜索原因,另外要檢查什么,以啟用任何其他日志記錄?

更新:有趣的是,原始電話也已完成。

更新2:我添加了動作過濾器AjaxOnly以確保它只能從javascript調用:

public class AjaxOnlyAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!filterContext.HttpContext.Request.IsAjaxRequest())
        {                  
            throw new Exception("This action is intended to be called from Ajax only.");
        }
    }
}

從日志中只能從javascript中調用它,所以神秘感繼續......

更新3:

我在單獨的測試控制器中將問題與簡單的線程睡眠隔離開來:

[ValidateAntiForgeryToken]
    [AjaxOnly]
    [ClientErrorHandler]
    public virtual ActionResult PlaceOrderAction(CheckoutDto checkoutDto)
    {
        try
        {
            if (CanPlaceOrder(Request.RequestContext.HttpContext))
            {                   
                Thread.Sleep(TimeSpan.FromSeconds(90));

                return Content("First time");
            }

            return Content("Second time");
        } 
        finally
        {
            HttpContext.Cache.Remove(GetKey(userService.CurrentUser.UserId));
        }
    }

    public bool CanPlaceOrder(HttpContextBase httpContext)
    {
        var userId = userService.CurrentUser.UserId;
        var key = GetKey(userId);

        if (httpContext.Cache[key] == null)
        {
            httpContext.Cache.Add(key, userId, null, DateTime.Now.AddMinutes(10), new TimeSpan(), CacheItemPriority.High, null);
            return true;
        }

        return false;
    }

    private static string GetKey(int userId)
    {
        return "PlacingOrder{0}".With(userId);
    }

只要它在兩個獨立的開發機器(win 7)和ec2(win2008sp2)中的升級機器上運行正常,生產服務器IIS設置(win 2008R2 x64 sp1)幾乎肯定是問題。

以下是類似問題的建議:

“是否有任何其他標記可能意外引用該頁面?腳本引用,圖像引用,CSS引用,都可能被錯誤地指向'。' 或當前頁面。“

MVC控制器被調用兩次

找到了。

正如我開始想的那樣,IIS配置在某種程度上與此有關,我已經在生產IIS上啟動了一個新的測試站點,只是默認的mvc站點,有90秒的線程休眠。
它起到了假設的作用。
所以我復制了整個生產站點以在不同的端口上運行,認為我能夠更快地測試想法而不影響生產站點 - 當它在不同的端口上運行時沒有問題。

事實證明,我們使用的是Amazon Elastic balancer,這就是問題所在。

道德是,如果我從一開始就是在侵略性地隔離問題,那么我會浪費更少的時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM