2014-10-10 11 views
10

पहचान नहीं मैं दोनों Attribute Routing और VersionedRouteRoutingConstaints Sample से लागू करने के लिए कोशिश कर रहा हूँ, लेकिन जब मैं एक नियंत्रक पर दोनों का उपयोग, संस्करणीकृत विशेषता नहीं रह गया काम करता है।वेब एपीआई 2 एपीआई रूटिंग (संशोधन) के लिए एकाधिक गुण

विशेषता रूटिंग के साथ अच्छा खेलने के लिए मुझे विशेषता पर संशोधित करने की क्या आवश्यकता होगी?

कोड उदाहरण के लिए डाउनलोड नमूना परियोजना (या बस ऊपर के लिंक से कुछ फाइलों को देखने) और फिर जैसे मार्गों को संशोधित:

// When I use the RoutePrefix, VersionedRoute no longer works (Sending "Api-Version" through http header doesn't route correctly 
// If I remove the RoutePrefix I can use VersionedRoute again 
// What do I need to change in its code to be able to use both? 

[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1" 
[RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers 
public class CustomersV1Controller : ApiController { 

    /* Other stuff removed */ 

    [VersionedRoute("api/Customer", 1)] // I'd rather not have to use this here at all and just use a single one on the class, but having both nor just one on either works right now. 
    [Route("")] 
    public IHttpActionResult Get() 
    { 
     return Json(_customers); 
    } 
} 

VersionedRoute Code

VersionConstraint Code

संपादित करें : कृपया मुझे बताएं कि आपको अधिक जानकारी चाहिए या यहां तक ​​कि विचारों या चीजों को पोस्ट करने के लिए पोस्ट करें :)

संपादित 2: यहां एक है मैं ट्रॉय हंट के ब्लॉग से क्या करने की कोशिश कर रहा हूं इसका उदाहरण: http://www.troyhunt.com/2014/02/your-api-versioning-is-wrong-which-is.html

संपादित 3: यहां मैं कोड के रूप में होना चाहता हूं क्योंकि यह बहुत सारे ओवरहेड और जादू तारों को कम करेगा।

[VersionedRoute("api/Customers", 1)] // This route would be used as http://url/api/customers with a header of "api-version: 1" 
[RoutePrefix("api/v1/Customers")] // This route would be used purely through url versioning of http://url/api/v1/Customers 
public class CustomersV1Controller : ApiController { 

    /* Other stuff removed */ 
    [Route("")] 
    public IHttpActionResult Get() 
    { 
     // Removed 
     return Ok(customers); 
    } 


    [Route("{id:int}")] 
    public IHttpActionResult GetById(int id) 
    { 
     // Removed 
     return Ok(customer); 
    } 
} 

[VersionedRoute("api/Customers", 2)] // This route would be used as http://url/api/customers with a header of "api-version: 2" 
[RoutePrefix("api/v2/Customers")] // This route would be used purely through url versioning of http://url/api/v2/Customers 
public class CustomersV2Controller : ApiController { 

    /* Other stuff removed */ 
    [Route("")] 
    public IHttpActionResult Get() 
    { 
     // Removed 
     return Ok(customersThatAreDifferentThanV1); 
    } 


    [Route("{id:int}")] 
    public IHttpActionResult GetById(int id) 
    { 
     // Removed 
     return Ok(customerThatIsDifferent); 
    } 
} 

संपादित करें: अंतिम टक्कर, केवल करने की कोशिश कर मार्ग प्रति एक बार मार्ग संस्करण जानकारी लिखने के लिए, नियंत्रक विशेषता स्तर पर और न प्रति-कार्य किया है।

+0

कि वास्तव में आप क्या करने की कोशिश कर रहे हैं:

[RoutePrefix("api")] public class CustomersV1Controller : ApiController { /* Other stuff removed */ [VersionedRoute("Customers", 1)] [Route("v1/Customers")] public IHttpActionResult Get() { return Json(_customers); } } 

एक सुधार ताकि आप संस्करण हर बार उपसर्ग की जरूरत नहीं होगी Route के बजाय स्वयं अपनी विशेषता बनाने के लिए हो सकता है? – DavidG

+0

@ डेविड जी मैं 'वर्जनड रूट ("ग्राहक", 1) दोनों का उपयोग करने की कोशिश कर रहा हूं, जो मुझे वर्जन # की आपूर्ति के साथ-साथ' रूट पेफिक्स ("v1/ग्राहक /") का उपयोग करने के लिए http शीर्षलेखों का उपयोग करने की अनुमति देगा। यूआरएल के माध्यम से संस्करण के लिए। असल में मैं हेडर और यूआरएल संस्करण दोनों का समर्थन करना चाहता हूं। हालांकि जब मैं 'रूटप्रिक्स' लागू करता हूं तो 'वर्जनड रूट' विशेषता काम करना बंद कर देती है। – John

+0

प्रोजेक्ट को सेट करते समय आपका कॉन्फ़िगरेशन कैसा दिखता है? – entropic

उत्तर

13

Route और VersionedRoute गुण एक साथ ठीक काम कर रहे हैं, लेकिन अपने RoutePrefix विशेषता भी अपने VersionedRoute (पहुंच बनाने का प्रयास/API/v1/ग्राहकों/api/ग्राहक के लिए लागू किया जाता है - आप एक प्रतिक्रिया मिल जाएगा जब api-संस्करण हैडर सेट है)

निम्नलिखित कोड आपके उदाहरण में दो यूआरएल के संबंध में वांछित व्यवहार का उत्पादन करेगा, सही प्रतिक्रियाओं को वापस कर रहा है, लेकिन स्पष्ट रूप से यह कक्षा के शीर्ष पर एक VersionedRoute और एक RoutePrefix की अपनी समस्या का समाधान नहीं करता है । इसके लिए एक और दृष्टिकोण की आवश्यकता होगी। हालांकि, आप विभिन्न एपीआई संस्करणों के लिए अलग नियंत्रक कर सकते हैं।

public class CustomVersionedRoute : Attribute, IHttpRouteInfoProvider 
{ 
    private readonly string _template; 

    public CustomVersionedRoute(string route, int version) 
    { 
     _template = string.Format("v{0}/{1}", version, route); 
    } 

    public string Name { get { return _template; } } 
    public string Template { get { return _template ; } } 
    public int Order { get; set; } 
} 

[RoutePrefix("api")] 
public class CustomersV2Controller : ApiController 
{ 
    /* Other stuff removed */ 

    [VersionedRoute("Customers", 2)] 
    [CustomVersionedRoute("Customers", 2)] 
    public IHttpActionResult Get() 
    { 
     return Json(_customers); 
    } 
} 
+0

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

+0

मेरा सवाल यह है कि मैं प्रत्येक के लिए 'वर्जनड रूट' और एक 'रूट पेफिक्स' कैसे प्राप्त करूं, इसलिए मुझे प्रत्येक विधि के ऊपर संस्करण की जानकारी डालने की चिंता करने की आवश्यकता नहीं है। मुझे पता है कि मैं इसे मैन्युअल रूप से प्रत्येक से ऊपर निर्दिष्ट कर सकता हूं लेकिन मैं इसे साफ और DRY रखना चाहता हूं। – John

+0

मुझे यकीन नहीं है। अगर यह मदद करता है, तो एक सुधार आपके द्वारा अपनाई गई 'रूट' विशेषता को साफ करना होगा (संपादन देखें), जिसे आप बस अपना कॉन्स्टा पास कर सकते हैं एनटीएस और एक संस्करण है, लेकिन आपको अभी भी प्रत्येक विधि पर दो विशेषताओं की आवश्यकता होगी, प्रत्येक मार्ग के लिए एक। – embee

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