11

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

Controllers 
| 
|---Version0 
|  | 
|  |----- ProjectController.cs 
|  |----- HomeController.cs 
| 
|---Version1 
     | 
     |----- ProjectController.cs 
     |----- HomeController.cs 

मैं मार्गों के लिए RoutingAttribute उपयोग कर रहा हूँ। तो, Version0 में ProjectController मैं 404-NotFound जब मैं सेवा हिट करने के लिए कोशिश कर रहा हूँ मिल

namespace MyProject.Controllers.Version0 
{ 
    class ProjectController : BaseController 
    { 
    ... 

    [Route(api/users/project/getProjects/{projectId})] 
    public async GetProjects(string projectId) 
    { 
     ... 
    } 
    } 
} 

और version1 में ProjectController रूप

namespace MyProject.Controllers.Version1 
{ 
    class ProjectController : BaseController 
    { 
    ... 

    [Route(api/v1/users/project/getProjects/{projectId})] 
    public async GetProjects(string projectId) 
    { 
     ... 
    } 
    } 
} 

मार्ग के साथ समारोह के रूप में मार्ग के साथ कार्य है लेकिन,।

यदि मैं नियंत्रकों का नाम बदलता हूं तो अद्वितीय नाम (Project1Controller और Project2Controller) रूटिंग कार्य करता है। लेकिन, मैं सादगी के लिए नाम बदलने से बचने की कोशिश कर रहा हूं।

मैंने इस मुद्दे को हल करने के लिए इस लिंक का पालन किया, लेकिन इससे मदद नहीं मिली। मैंने क्षेत्रों को बनाया लेकिन अभी भी कोई सफलता नहीं मिली। Global.aspx फ़ाइल में रूटिंग तर्क जोड़ना मदद नहीं करता है। नामस्थान या तो काम नहीं करता है। http://haacked.com/archive/2010/01/12/ambiguous-controller-names.aspx/

ऊपर के लिंक क्षेत्रों बनाने के लिए सुझाव देते हैं, लेकिन विशेषता मार्ग प्रति कड़ी के रूप में क्षेत्रों का समर्थन नहीं करते: http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

वहाँ एक और समाधान है? रूटिंग एट्रिब्यूट्स के साथ एक बग?

धन्यवाद!

+0

वी 0 और वी 1 नियंत्रकों के लिए नेमस्पेस क्या है? –

+0

@ पंकज: नामस्थान MyProject.Controllers.Version0 और MyProject.Controllers.Version1 – rkd

+0

दुर्भाग्यवश यह दृष्टिकोण WebApi के साथ काम नहीं करेगा। अधिक जानकारी के लिए [यह] देखें (http://blogs.msdn.com/b/webdev/archive/2013/03/08/using-namespaces-to-version-web-apis.aspx) लिंक –

उत्तर

15

पहला, वेब एपीआई रूटिंग, और एमवीसी रूटिंग बिल्कुल उसी तरह काम नहीं करता है।

आपका पहला लिंक क्षेत्रों के साथ एमवीसी रूटिंग के लिए इंगित करता है। क्षेत्रों को आधिकारिक तौर पर वेब एपीआई के लिए समर्थित नहीं है, हालांकि आप उनके जैसा कुछ करने की कोशिश कर सकते हैं। हालांकि, भले ही आप ऐसा कुछ करने का प्रयास करें, आपको वही त्रुटि मिल जाएगी, क्योंकि जिस तरह से वेब एपीआई नियंत्रक की तलाश में है, वह नियंत्रक के नामस्थान को ध्यान में रखता नहीं है।

तो, बॉक्स के बाहर, यह कभी काम नहीं करेगा।

हालांकि, आप अधिकांश वेब एपीआई व्यवहार संशोधित कर सकते हैं, और यह एक अपवाद नहीं है।

वेब एपीआई वांछित नियंत्रक प्राप्त करने के लिए एक नियंत्रक चयनकर्ता का उपयोग करता है। ऊपर वर्णित व्यवहार DefaultHttpControllerSelector का व्यवहार है, जो वेब एपीआई के साथ आता है, लेकिन आप डिफ़ॉल्ट को प्रतिस्थापित करने के लिए अपने स्वयं के चयनकर्ता को कार्यान्वित कर सकते हैं और नए व्यवहार का समर्थन कर सकते हैं।

आप "कस्टम वेब एपीआई नियंत्रक चयनकर्ता के लिए" गूगल यदि आप कई नमूने मिल जाएगा, लेकिन मैं इस सबसे बिल्कुल आपकी समस्या के लिए दिलचस्प:

इस कार्यान्वयन है यह भी दिलचस्प:

तुम्हें वहाँ देखने के रूप में, मूल रूप से आप की जरूरत है:

  • अपनी खुद की IHttpControllerSelector, जो नियंत्रकों को खोजने के लिए खाते के नामस्थान में ले जाता है, और नामस्थान मार्ग चर को लागू है, उनमें से एक को चुनना।
  • वेब एपीआई कॉन्फ़िगरेशन के माध्यम से इसके साथ मूल चयनकर्ता को प्रतिस्थापित करें।
+0

धन्यवाद! मुझे इसे एक मौका और देना होगा। – rkd

+0

इसके लिए धन्यवाद। – tremolo

+0

'नेमस्पेस से वर्जन वेब एपीआई' लेख के लिए मूल लिंक टूटा हुआ है। मुझे लगता है कि यह सही नया लिंक है: https://blogs.msdn.microsoft.com/webdev/2013/03/07/asp-net-web-api-using-namespaces-to-version-web-apis/ – Moo

1

मुझे पता है कि यह थोड़ी देर के लिए उत्तर दिया गया था और मूल पोस्टर द्वारा पहले ही स्वीकार कर लिया गया है। हालांकि यदि आप मेरे जैसे हैं और विशेषता रूटिंग के उपयोग की आवश्यकता है और सुझाए गए उत्तर की कोशिश की है तो आपको पता चलेगा कि यह काफी काम नहीं करेगा।

जब मैं इस कोशिश की मुझे पता चला कि यह वास्तव में रूटिंग जानकारी है कि HttpConfiguration वर्ग के विस्तार विधि MapHttpAttributeRoutes बुला द्वारा उत्पन्न किया जाना चाहिए था याद आ रही थी:

config.MapHttpAttributeRoutes(); 

मतलब यह कि की विधि SelectController प्रतिस्थापन IHttpControllerSelector कार्यान्वयन वास्तव में कभी नहीं बुलाया जाता है और यही कारण है कि अनुरोध http 404 प्रतिक्रिया उत्पन्न करता है।

समस्या HttpControllerTypeCache नामक एक आंतरिक वर्ग के कारण होती है जो नामस्थान के तहत System.Web.Http असेंबली में एक आंतरिक वर्ग है।

private Dictionary<string, ILookup<string, Type>> InitializeCache() 
    { 
     return this._configuration.Services.GetHttpControllerTypeResolver().GetControllerTypes(this._configuration.Services.GetAssembliesResolver()).GroupBy<Type, string>((Func<Type, string>) (t => t.Name.Substring(0, t.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length)), (IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase).ToDictionary<IGrouping<string, Type>, string, ILookup<string, Type>>((Func<IGrouping<string, Type>, string>) (g => g.Key), (Func<IGrouping<string, Type>, ILookup<string, Type>>) (g => g.ToLookup<Type, string>((Func<Type, string>) (t => t.Namespace ?? string.Empty), (IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase)), (IEqualityComparer<string>) StringComparer.OrdinalIgnoreCase); 
    } 

आप इस कोड है कि यह नाम स्थान के बिना प्रकार नाम से समूहीकरण में देखेंगे: प्रश्न में कोड इस प्रकार है। प्रत्येक नियंत्रक के लिए HttpControllerDescriptor के आंतरिक कैश का निर्माण करते समय DefaultHttpControllerSelector कक्षा इस कार्यक्षमता का उपयोग करती है। MapHttpAttributeRoutes विधि का उपयोग करते समय यह AttributeRoutingMapper नामक एक और आंतरिक वर्ग का उपयोग करता है जो System.Web.Http.Routing नामस्थान का हिस्सा है। मार्गों को कॉन्फ़िगर करने के लिए यह कक्षा IHttpControllerSelector की विधि GetControllerMapping का उपयोग करती है।

तो अगर आप एक कस्टम IHttpControllerSelector लिखने के लिए जा रहे हैं तो आप यह काम करने के लिए के लिए GetControllerMapping विधि ओवरलोड की जरूरत है। इसका कारण यह है कि इंटरनेट पर मैंने जो भी कार्यान्वयन देखा है, वह ऐसा नहीं करता है।

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