2012-07-20 10 views
7

मुझे अजीब व्यवहार है, जो स्थानीय मशीन पर दोहराना नहीं कर सकता है और यह मुझे पागल ड्राइव करना शुरू कर रहा है।नियंत्रक कार्रवाई को दो बार बुलाया जा रहा है और आईआईएस लॉग यह नहीं दिखाते हैं कि

ऐसा लगता है कि एएसपी.नेट एमवीसी कार्रवाई निष्पादित करने की कोशिश कर रहा है, कुछ टाइमआउट, यह किसी भी अपवाद के बिना विफल रहता है और 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 
       } 
      }); 

और छोटे आदेश के लिए यह ठीक काम करता है, लेकिन बड़े आदेश के लिए दो आदेश बनाया है और कारण कर रहे हैं प्रतीत होता है कि समय प्रसंस्करण हो रहा है, ऑर्डर जितना बड़ा होगा, बाहरी webservice को रखने में अधिक समय लगेगा।

मैंने आईआईएस लॉग की जांच की है, यह सुनिश्चित करने के लिए कि क्लाइंट स्क्रिप्ट दो बार कार्रवाई नहीं कर रही है - और आईआईएस लॉग विशेष कार्रवाई के लिए केवल एक कॉल दिखाते हैं।

बाहरी सेवा विफल नहीं है, इवेंट लॉग/एसक्यूएल लॉग में कोई अपवाद लॉग नहीं है।

सुनिश्चित करने के लिए, कि 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 यकीन है, कि यह केवल जावास्क्रिप्ट से कहा जाता है होना करने के लिए कार्रवाई फिल्टर जोड़ दिया है:

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."); 
     } 
    } 
} 

और लॉग यह केवल जावास्क्रिप्ट से कहा जाता है से, इसलिए रहस्य जारी है ...

अद्यतन 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); 
    } 

जब तक यह दो स्वतंत्र देवताओं (जीत 7) और ec2 (win2008sp2) में स्टेजिंग मशीन पर ठीक चलता है, यह उत्पादन सर्वर आईआईएस सेटिंग्स (2008R2 x64 sp1 जीतने) के साथ लगभग निश्चित रूप से समस्या है। ?

+0

लंबी कॉल के लिए async का उपयोग करें जो टाइमआउट कर सकते हैं। आप एक टोकन रद्द कर सकते हैं। मेरे ट्यूटोरियल देखें http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4 – RickAndMSFT

उत्तर

0

यह मिला।

मुझे लगता है कि करने के लिए शुरू कर दिया है के रूप में, कि IIS कॉन्फ़िगरेशन किसी भी तरह इस के लिए involded है, मैं उत्पादन आईआईएस पर एक नया परीक्षण स्थल शुरू कर दिया है, बस MVC साइट डिफ़ॉल्ट 90 सेकंड थ्रेड नींद के साथ।
और यह माना जाता है कि
तो मैंने अलग-अलग बंदरगाह पर चलाने के लिए पूरी उत्पादन साइट की प्रतिलिपि बनाई है, सोच रहा हूं कि मैं उत्पादन साइट को प्रभावित किए बिना विचारों का तेजी से परीक्षण करने में सक्षम हूं - और जब यह चल रहा था विभिन्न बंदरगाह पर कोई समस्या नहीं थी।

बाहर निकलता है, कि हम अमेज़ॅन लोचदार बैलेंसर का उपयोग कर रहे थे और यह समस्या थी।

नैतिक है, कि अगर मैं आक्रामक रूप से शुरुआत से ही समस्या को अलग कर रहा था तो मैं बहुत कम समय बर्बाद कर देता।

0

यहाँ एक समान प्रश्न से सुझाव है: '।'

"क्या कोई अन्य मार्कअप कि गलती से पेज को संदर्भित किया जा सकता है सब गलती से हो सकता है की दिशा में रखे है स्क्रिप्ट संदर्भ, छवि संदर्भ, सीएसएस संदर्भ, या वर्तमान पृष्ठ।"

MVC controller is being called twice

+0

मैंने इसे देखा है, लेकिन ऐसा नहीं है क्योंकि यह कोई मामला नहीं है क्योंकि) आईआईएस लॉग अभी भी 2 कॉल दिखाएंगे बी) यह सभी ऑर्डर के लिए दो बार कॉल करेगा, न केवल बड़े वाले सी) मैंने एजेक्स से एक्शन को कॉल करने की अनुमति देने के लिए फ़िल्टर जोड़ा है – Giedrius

संबंधित मुद्दे