HttpClient BaseAddress काम क्यों नहीं कर रहा है?


299

निम्नलिखित कोड पर विचार करें, जहां BaseAddress एक आंशिक यूआरआई मार्ग परिभाषित करता है।

using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
    client.BaseAddress = new Uri("http://something.com/api");
    var response = await client.GetAsync("/resource/7");
}

मैं उम्मीद करता हूं कि यह एक प्रदर्शन करे GET अनुरोध करने केhttp://something.com/api/resource/7 । लेकिन यह नहीं है।

कुछ खोज के बाद, मुझे यह प्रश्न और उत्तर मिला: बेसड्रेस के साथ HttpClient । सुझाव /के अंत में जगह है BaseAddress

using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
    client.BaseAddress = new Uri("http://something.com/api/");
    var response = await client.GetAsync("/resource/7");
}

यह अभी भी काम नहीं करता है। यहाँ प्रलेखन है: HttpClient.BaseAddress यहाँ क्या चल रहा है?



@ ГеоргийЛанец रिवर्स डुप्लिकेट पहले से ही प्रस्तावित किया गया है। मैंने यह प्रश्न विशेष रूप से लिखा था क्योंकि उस प्रश्न को अन्य तरीके से नहीं लिखा गया था, जो एक ही समस्या वाले लोगों द्वारा बहुत खोजा गया था, और मैंने इसका उत्तर यहाँ लिखा था क्योंकि वहाँ पर जवाब एक महत्वपूर्ण बिंदु को छोड़ दिया था।
तीमुथियुस

लेकिन यह सवाल बाद में पूछा गया
जॉर्ज लैंटेज़

2
@ ГеоргийЛанец यह काम नहीं करता है। आमतौर पर सबसे "विहित" प्रश्न वह है जो डुप्लिकेट को इंगित करता है। यह अन्य प्रश्न एक एकल समस्या के बारे में था जो उपयोगकर्ता को अक्सर पूछे जाने वाले प्रश्न की तरह पढ़ने के बजाय होती थी।
तीमुथियुस

2
@ ГеоргийЛанец इसके अलावा मैं इस प्रश्न में अन्य प्रश्न का संदर्भ देता हूं, और मैं समझाता हूं कि समस्या को हल करने के लिए अन्य प्रश्न और उत्तर अपर्याप्त क्यों हैं।
तीमुथियुस

जवाबों:


719

यह पता चला है कि, या BaseAddressसंबंधित URI GetAsyncविधि पर या उसके बाद आने वाले स्लैश को शामिल करने या बाहर करने के चार संभावित क्रमपरिवर्तन में से - या जो भी अन्य विधि से HttpClient- केवल एक क्रमपरिवर्तन कार्य करता है। आप चाहिए के अंत में एक स्लेश जगह BaseAddressहै, और आप नहीं होना चाहिए अपने सापेक्ष URI की शुरुआत में एक स्लैश जगह, निम्न उदाहरण में।

using (var handler = new HttpClientHandler())
using (var client = new HttpClient(handler))
{
    client.BaseAddress = new Uri("http://something.com/api/");
    var response = await client.GetAsync("resource/7");
}

हालांकि मैंने अपने प्रश्न का उत्तर दिया, मुझे लगा कि मैं यहाँ समाधान का योगदान दूंगा, फिर से, यह अमित्र व्यवहार अनिर्दिष्ट है। मेरे सहयोगी और मैंने उस समस्या को ठीक करने के लिए दिन का अधिकांश समय बिताया जो अंततः इस विषमता के कारण थी HttpClient


4
धन्यवाद। उस समस्या को हल कर दिया है, जिसे मैं अब तक दो दिनों के लिए संघर्ष कर रहा हूं, एज़्योर पर वापस जाने के बीच, आईआईएस में वापस, और वापस आईआईएस एक्सप्रेस में, जो कि ज्यादातर गलत तरीके से गलत या अतिरिक्त फॉरवर्ड स्लैश को अनदेखा करता है। एक बार मेरे बेस क्लास में सेट हो जाने के बाद RestClient, यह लगभग अदृश्य था और इस पर बिल्कुल भी ध्यान नहीं दिया गया, और मैंने कभी भी अपने ब्रेकपॉइंट्स आदि में पूरा url नहीं देखा
ProfK

43
मैं पुष्टि कर सकता हूं कि यह विषमता (और यह फिक्स) अभी भी .NET कोर में प्रासंगिक है। मेरे बाल खींचने वाले टिमोथी को कम करने के लिए धन्यवाद।
नैट बारबेटिनी

8
इसका कारण यह है कि जब यह पिछले भाग को छोड़ देता है तो अनुरोधों को पीछे हटाते हुए स्लैश के बिना। तो यह कुछ हिट करता है । यदि आप आधार पते को कुछ / कॉम के रूप में सेट करते हैं (यदि कोई फर्क नहीं पड़ता है या स्लैश को पीछे किए बिना) तो यह भी कोई फर्क नहीं पड़ता है कि यदि आप एपीआई / संसाधन / 7 की शुरुआत में स्लैश डालते हैं। आधार पते के अंतिम भाग को पीछे हटाए बिना फ़ाइल की तरह व्यवहार किया जाता है और जब अनुरोध किया जाता है तो उसे गिरा दिया जाता है।
पायोत्र पेरक

12
यह मूल प्रश्न पर सीधे संबंधित नहीं है। प्रति Mircosoft, HttpClient () का एक उदाहरण एक स्थिर चर को सौंपा जाना चाहिए और पुन: उपयोग किया जाना चाहिए ( docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/…Creating a new HttpClient instance per request can exhaust the available sockets ) - । तो आपको उपयोग करके हटाने पर विचार करना चाहिए ()।
sanmcp

6
बस एक भयानक कार्यान्वयन। वे इसे ठीक क्यों नहीं करते?
तैमूरक्रूज

55

संदर्भ रिज़ॉल्यूशन RFC 3986 यूनिफ़ॉर्म रिसोर्स आइडेंटिफ़ायर (URI) द्वारा वर्णित है : जेनेरिक सिंटैक्स । और यह ठीक है कि यह कैसे काम करना चाहिए। आधार URI पथ को संरक्षित करने के लिए आपको आधार URI के अंत में स्लैश जोड़ना होगा और सापेक्ष URI की शुरुआत में स्लैश को हटाना होगा।

यदि आधार URI में गैर-रिक्त पथ है, तो मर्ज प्रक्रिया को अंतिम भाग (अंतिम के बाद /) में विलय कर देता है । प्रासंगिक अनुभाग :

5.2.3। माग पथ

ऊपर छद्मकोड एक "मर्ज" दिनचर्या को संदर्भित करता है जो आधार यूआरआई के पथ के साथ एक रिश्तेदार-पथ संदर्भ को विलय करने के लिए है। इसे निम्न प्रकार से पूरा किया जाता है:

  • यदि आधार यूआरआई में एक परिभाषित प्राधिकारी घटक और एक खाली पथ है, तो संदर्भ के पथ के साथ "/" से मिलकर एक स्ट्रिंग लौटाएं; अन्यथा

  • संदर्भ स्ट्रिंग पथ घटक से युक्त एक स्ट्रिंग लौटाएं, जो आधार URI पथ में आधार URI के पथ के अंतिम खंड (लेकिन, किसी भी वर्ण को छोड़कर, किसी भी वर्ण को छोड़कर, URI पथ में या संपूर्ण आधार URI पथ को छोड़कर) कोई भी "/" वर्ण नहीं है)।

यदि सापेक्ष URI स्लैश से शुरू होता है, तो इसे निरपेक्ष-पथ सापेक्ष URI कहा जाता है। इस मामले में मर्ज प्रक्रिया सभी आधार यूआरआई पथ की उपेक्षा करती है। अधिक जानकारी के लिए 5.2.2 की जाँच करें ट्रांसफ़रेंस संदर्भ अनुभाग।


3
HttpClient जैसी बारीक लेकिन क्लाइंट लाइब्रेरियों को इस तरह गूढ़ कार्यान्वयन विवरण से हमें अलग करना चाहिए।
जेमी इडे

-1

HTTPClient के साथ एक समस्या में भाग गए, यहां तक ​​कि सुझावों के साथ अभी भी इसे प्रमाणित करने के लिए नहीं मिला। पता चलता है कि मुझे अपने रिश्तेदार मार्ग में एक अनुगामी '/' की आवश्यकता थी।

अर्थात

var result = await _client.GetStringAsync(_awxUrl + "api/v2/inventories/?name=" + inventoryName);
var result = await _client.PostAsJsonAsync(_awxUrl + "api/v2/job_templates/" + templateId+"/launch/" , new {
                inventory = inventoryId
            });

-6

वैकल्पिक रूप से - बिल्कुल भी उपयोग न करें BaseAddress। पूरे URL को GetAsync() में डालें


33
जो भी सवाल का जवाब नहीं देता है।
आर्किबाल्ड

7
बेसअड्रेस शोर को कम करता है। मेरी आँखों के लिए वैसे भी। :)
११

2
मुझे नकारात्मक टिप्पणियों से असहमत होना पड़ेगा। मैंने 2 दिन बिताए हैं यह जानने की कोशिश कर रहा हूं कि मेरे HttpClient कॉल मेरे देव पीसी पर काम क्यों करते हैं लेकिन सर्वर पर टूट जाते हैं। अजीब तरह से काम करता है, लेकिन .net नहीं करता है। मैं उपयोग कर रहा था। सेंडेसाइक तब मुझे पता चला कि .GetAsyc ने काम किया। इससे मुझे एक अलग राह मिली और आखिरकार यहाँ। आधार पते और संबंधित URL के बीच / को जोड़ने या हटाने से कुछ नहीं हुआ। फिर भी 404 त्रुटियां हुईं .... हालांकि जब मैंने आधार पता निर्धारित नहीं किया, और पूरे रास्ते को सापेक्ष में रख दिया .. तो यह काम कर गया! फिर से, यह .SendAsync के साथ है, लेकिन 2 दिन थे मैं कभी वापस नहीं लाऊंगा!
da_jokker
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.