2017-01-20 12 views
6

पोस्ट करना मुझे Azure में होस्ट की गई एक वेब एपीआई सेवा में डेटा पोस्ट करते समय एक अजीब समस्या का सामना करना पड़ रहा है और किसी भी अंतर्दृष्टि की सराहना करता है।जेएसओएन डेटा वेबएपीआई

मैंने एक सुंदर मूल वेब एपीआई सेवा लिखी है जिसमें एक नियंत्रक है जो एक पोस्ट विधि के माध्यम से एक सूची प्राप्त करता है। मैं HttpClientFactory से बनाए गए क्लाइंट का उपयोग कर कंसोल एप्लिकेशन के माध्यम से इस एपीआई में डेटा पोस्ट कर रहा हूं।

जब मैं इसे स्थानीय रूप से डीबग करता हूं तो सभी अच्छी तरह से काम करता है और मैंने 100 तत्वों वाली एक सूची पोस्ट की है और इसे मेरे स्थानीय डेटाबेस में लिखा है। अगर मैं अपने एज़ूर डेटाबेस को इंगित करने के लिए अपना स्थानीय वेब एपीआई कोड स्विच करता हूं तो यह अभी भी सभी अच्छी तरह से काम करता है और मैं बिना किसी समस्या के 100 तत्व प्राप्त कर सकता हूं और Azure डीबी इंस्टेंस को लिख सकता हूं।

जब मैं अपने एज़ूर खाते में एपीआई सेवा को तैनात करता हूं और अपने कंसोल एप्लिकेशन को डेटा पोस्ट करने के लिए हुक करता हूं - यह 45 तत्वों तक की एक सूची के साथ पूरी तरह से काम करता है, और पोस्टएसिंक लगभग 6 मिनट तक प्रतीक्षा करता है और फिर विफल रहता है एक आंतरिक सर्वर त्रुटि के साथ।

तो मेरा सवाल यह है कि सेवा 44 तत्वों के साथ विफल होने के लिए लगभग एक सेकंड में 43 तत्वों को पोस्ट करने में सक्षम होने से क्यों जाती है, लेकिन ऐसा करने में 6 मिनट लगते हैं?

मुझे इंगित करना चाहिए कि मेरी सूची में 100 डुप्लिकेट आइटम हैं क्योंकि मैं परीक्षण के लिए डेटा उत्पन्न कर रहा हूं इसलिए सेट के भीतर किसी विशेष तत्व के साथ कुछ भी गलत (या अलग) नहीं है।

टी लगभग 30 गुणों के साथ सरल वर्ग है और कोई बाल तत्व नहीं है इसलिए मैं एक विशाल संरचना पोस्ट नहीं कर रहा हूं।

मेरी सोच यह है कि यह कहीं भी एक आकार प्रतिबंध होना है जो मेरी स्थानीय मशीन पर प्रभाव नहीं डाल रहा है, लेकिन जब मैं Azure पर तैनात करता हूं। मैं किसी भी तरह से एक वेब एपीआई विशेषज्ञ नहीं हूं इसलिए मुझे यकीन नहीं है कि कहां देखना शुरू करना है।

कुछ क्लाइंट कोड (पूरी तरह से काम करता है जब मैं < = 43):

List<Foo> results = new List<Foo>(); 

for (int i = 1; i < 100; i++) 
{ 
    results.Add(new Foo() { // Populated with data - removed for brevity }); 
} 

StringContent content = new StringContent(JsonConvert.SerializeObject(results), Encoding.UTF8, "application/json"); 
HttpResponseMessage postDataResponse = await postClient.PostAsync(myWebApiServiceURL, content); 

नियंत्रक विधि:

: कोई प्रभाव नहीं है कि

[HttpPost] 
public List<Foo>Post([FromBody]List<Foo> value) 
{ 
    return value; 
} 

Web.config सेटिंग्स मैं कोशिश की है

<httpRuntime targetFramework="4.6.1" maxRequestLength="200000000" requestLengthDiskThreshold="16384" /> 

और

<add key="aspnet:MaxJsonDeserializerMembers" value="20000000"/> 

मैं सिर्फ एक परीक्षण भाग गया है और यह 44 तत्वों सामग्री की लंबाई के साथ काम नहीं करता है = 53278

अधिकतम लंबाई यह तब होता है जब मेरी कुल तत्वों 43 सामग्री की लंबाई हैं पर काम करता है = 48361.

नोट: मैंने अभी कुछ और परीक्षण चलाए हैं और यदि मैं अपनी कुछ स्ट्रिंग गुणों में डेटा लंबाई को कम करता हूं (जिससे प्रत्येक तत्व के पदचिह्न को कम करता है) मैं और तत्व पोस्ट कर सकता हूं। इसलिए इसे कहीं संदेश आकार प्रतिबंध होना है !!

अद्यतन - HMAC प्रमाणीकरण

ठीक कारण हमेशा कम से कम की उम्मीद बात यह है कि आप प्रश्न में दस्तावेज़ नहीं है।मेरे पास मेरे एपीआई पर एचएमएसी प्रमाणीकरण सक्षम है और जब मैं अपने नियंत्रक से विशेषता हटाता हूं तो मैं बिना किसी समस्या के 10000 तत्व पोस्ट कर सकता हूं। जैसे ही मैं इसे सक्षम करता हूं, मैं 43 तक सीमित हूं।

क्लाइंट पर मैं हेडर हस्ताक्षर के हिस्से के रूप में अनुरोध सामग्री का MD5 हैश उत्पन्न कर रहा हूं, इस प्रक्रिया को वेब पर एचएमएसी विशेषता में दोहराया जा रहा है एपीआई सेवा। अगर मैं अपने ग्राहक और सेवा दोनों से हस्ताक्षर के इस हिस्से को हटा देता हूं तो मैं जितना चाहूं उतना डेटा पोस्ट कर सकता हूं। कोड मैं ग्राहक पर बाहर टिप्पणी की है नीचे दिखाया गया है:

//Checking if the request contains body, usually will be null with HTTP GET and DELETE 
if (request.Content != null) 
{ 
    byte[] content = await request.Content.ReadAsByteArrayAsync(); 
    MD5 md5 = MD5.Create(); 
    //Hashing the request body, any change in request body will result in different hash, we'll incure message integrity 
    byte[] requestContentHash = md5.ComputeHash(content); 
    requestContentBase64String = Convert.ToBase64String(requestContentHash); 
} 

कोड मैं सेवा में बाहर टिप्पणी की है नीचे है:

byte[] hash = await ComputeHash(req.Content); 

if (hash != null) 
{ 
    requestContentBase64String = Convert.ToBase64String(hash); 
} 

ComputeHash समारोह:

private static async Task<byte[]> ComputeHash(HttpContent httpContent) 
{ 
    using (MD5 md5 = MD5.Create()) 
    { 
     byte[] hash = null; 
     var content = await httpContent.ReadAsByteArrayAsync(); 
     if (content.Length != 0) 
     { 
     hash = md5.ComputeHash(content); 
     } 
     return hash; 
    } 
} 

तो उपर्युक्त कोड के साथ requestContentBase64String हमेशा ग्राहक और सर्वर दोनों पर एक खाली स्ट्रिंग है, इसलिए सामग्री के MD5 हैश को प्रमाणीकरण के हिस्से के रूप में उपयोग नहीं किया जा रहा है आयन हस्ताक्षर।

अब मुझे इस व्यवहार के मूल कारण का शोध करना है।

+0

एस्पनेट जोड़ने का प्रयास करें: MaxJsonDeserializerMembers web.config में appSettings के अंतर्गत। अपने जेसन की लंबाई की जांच करें और इसे

+0

@AliBaig मैंने कोशिश की है कि ' 'बिना किसी प्रभाव के। – CSL

+0

क्या आपने maxRequestLength आकार को सेट करने का भी प्रयास किया है? – xszaboj

उत्तर

0

https://blogs.msdn.microsoft.com/azureossds/2016/06/15/uploading-large-files-to-azure-web-apps/

Azure के लिए अपनी अधिकतम पद आकार की जाँच करें। आपके कॉन्फ़िगरेशन के आधार पर यह समस्या हो सकती है। या तो कॉन्फ़िगरेशन बदलें या पोस्ट आकार को छोटे हिस्सों में कम करने पर देखें।

+0

सुझाव के लिए धन्यवाद लेकिन मैं इतना डेटा पोस्ट नहीं कर रहा हूं (मेगाबाइट से कम) और यदि मैं एचएमएसी प्रमाणीकरण को हटाता हूं तो मैं बिना किसी मुद्दे के एज़ूर के माध्यम से बड़ी मात्रा में पोस्ट कर सकता हूं। यह प्रमाणीकरण विशेषता के कार्यान्वयन में कहीं कहीं है। मैंने अभी तक मूल कारण के साथ आने के लिए पर्याप्त समय की जांच नहीं की है। – CSL

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