2014-04-21 5 views
29

एएसपी.नेट वेब एपीआई 2 में, निम्नलिखित में क्या अंतर है?रिटर्निंग IHttpActionResult बनाम IENumerable <Item> बनाम IQueryable <Item>

public async Task<IEnumerable<MyItem>> GetMyItems() 
{ 
    //... code ..., var myItems = await ... 
    return myItems; 
} 

और

public async Task<IQueryable<MyItem>> GetMyItems() 
{ 
    //... code ..., var myItems = await ... 
    return myItems; 
} 

और

public async Task<IHttpActionResult> GetMyItems() 
{ 
    //... code ..., var myItems = await ... 
    return Ok(myItems); 
} 

मैं IHttpActionResult या IEnumerable<MyItem>/IQueryable<MyItem> लौट जाना चाहिए?

+0

यदि आपकी क्रिया विधि में 'प्रतीक्षा' कीवर्ड का उपयोग शामिल नहीं है, तो आपको 'कार्य' वापस नहीं करना चाहिए।इसके बजाय, आपको बस 'IHttpActionResult',' IENumerable 'या 'IQueryable ' वापस करना चाहिए। प्रश्न देखें [IHttpActionResult बनाम async कार्य ] (https://stackoverflow.com/q/29100732/1497596)। यह प्रश्न भी देखें [एएसपी.NET वेब एपीआई के साथ प्रभावी रूप से async/प्रतीक्षा करें] (https://stackoverflow.com/q/31185072/1497596)। – DavidRR

उत्तर

24

आपको IHttpActionResult वापस करना चाहिए क्योंकि आप ग्राहक के लिए अधिक विशिष्ट हो सकते हैं। आप अधिक उपयोगकर्ता के अनुकूल वेब अनुप्रयोग बना सकते हैं। असल में आप विभिन्न स्थितियों के लिए अलग-अलग HTML स्थिति संदेश वापस कर सकते हैं।

उदाहरण के लिए:

public async Task<IHttpActionResult> GetMyItems() 
{ 
    if(!authorized) 
     return Unauthorized(); 
    if(myItems.Count == 0) 
     return NotFound(); 
    //... code ..., var myItems = await ... 
    return Ok(myItems); 
} 

IEnumerable और IQueryable सिर्फ उत्पादन प्रारूप में अपने डेटा को पार्स जाएगा और आप अपवाद को संभालने के लिए एक उचित तरीके से नहीं होगा। यह सबसे महत्वपूर्ण अंतर है।

+0

यह देखते हुए कि 'GetMyItems()' के भीतर 'प्रतीक्षा' का उपयोग नहीं किया जाता है, इसका हस्ताक्षर केवल 'IHttpActionResult GetMyItems() 'होना चाहिए। प्रश्न से [IHttpActionResult बनाम एसिंक कार्य ] (https://stackoverflow.com/q/29100732/1497596), [यह उत्तर] देखें (https://stackoverflow.com/a/38699810/1497596) जो बताता है : "यदि आपका नियंत्रक एक्शन कोड 'प्रतीक्षा' का उपयोग नहीं करता है तो आप वापस सरल हस्ताक्षर पर स्विच कर सकते हैं। हालांकि, आपके द्वारा वापस आने वाला परिणाम अभी भी असीमित होगा।" – DavidRR

6

मैं आईन्यूमेरेबल और आईएचटीपीएक्शन रिसेट के बीच चयन करूंगा, आप इन दोनों के साथ थोड़ा अलग तरीके से एक ही चीज़ कर सकते हैं। IQueryable आमतौर पर निचले स्तर के डेटा एक्सेस कार्यों और एसक्यूएल प्रश्नों के स्थगित निष्पादन के लिए उपयोग किया जाता है, इसलिए मैं इसे आपके डेटा एक्सेस क्लास में encapsulated रखूंगा और इसे वेब एपीआई के साथ बेनकाब नहीं करूँगा। ,

IHttpActionResult

IHttpActionResult इंटरफ़ेस अनिवार्य रूप से वेब एपीआई 2 में introducted गया था यह एक HttpResponseMessage कारखाने परिभाषित करता है:

यहाँ एक http://www.asp.net/web-api/overview/web-api-routing-and-actions/action-results से सारांश है।

  • सरल इकाई अपने नियंत्रकों का परीक्षण: यहाँ IHttpActionResult इंटरफ़ेस (HttpResponseMessage वर्ग से अधिक) का उपयोग करने के कुछ लाभ हैं।
  • अलग-अलग वर्गों में HTTP प्रतिक्रियाएं बनाने के लिए सामान्य तर्क चलाता है।
  • प्रतिक्रिया बनाने के निम्न-स्तर के विवरण छिपाकर, नियंत्रक कार्रवाई स्पष्ट करने का इरादा बनाता है।

IEnumerable < आइटम >

अन्य सभी प्रकार के लिए वापसी, जाल एपीआई वापसी मान क्रमानुसार करने एक मीडिया फ़ॉर्मेटर उपयोग करता है। वेब एपीआई प्रतिक्रिया शरीर में धारावाहिक मूल्य लिखता है। प्रतिक्रिया स्थिति कोड 200 (ठीक है) है।

public class ProductsController : ApiController 
{ 
    public IEnumerable<Product> Get() 
    { 
     return GetAllProductsFromDB(); 
    } 
} 

इस दृष्टिकोण का एक नुकसान यह है कि आप सीधे एक त्रुटि कोड नहीं दे सकता है, इस तरह के रूप में हालांकि 404., आप त्रुटि कोड के लिए एक HttpResponseException फेंक कर सकते हैं। अधिक जानकारी के लिए।

+2

-1 "IQueryable आमतौर पर निचले स्तर के डेटा एक्सेस कार्यों और एसक्यूएल प्रश्नों के स्थगित निष्पादन के लिए उपयोग किया जाता है, इसलिए मैं इसे आपके डेटा एक्सेस क्लास में encapsulated रखता हूं और इसे वेब एपीआई के साथ बेनकाब नहीं करता हूं।" यह पूरी तरह गलत है। IQueryable को उजागर किए बिना, 'ओडाटा' क्वेरी यूआरएल का उपयोग करना मुश्किल है। http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/create-an-odata-v4-endpoint – Aron

+1

@Aron मैं मानता हूं कि यह नहीं है ओडाटा पर लागू करें, लेकिन बहुत से लोग रिपोजिटरी परत के बाहर IQueryable को उजागर करने के बारे में आपसे असहमत होंगे: http://codetunnel.com/should-you-return-iqueryablet-from-your-repositories/, http: // प्रोग्रामर .stackexchange.com/प्रश्न/192044/चाहिए-रिपॉजिटरीज-रिटर्न-इक्वरीबल, http://mikehadlow.blogspot.com.au/2009/01/should-my-repository-expose-iqueryable.html। और कुछ लोग ओडाटा को एक विरोधी पैटर्न के रूप में भी वर्णन करते हैं https://github.com/ServiceStack/ServiceStack/wiki/Auto-Query#why-not-odata – Jason

+0

वे वही लोग हैं जो मैं तर्क दूंगा कि आंतरिक मंच एक विरोधी है पैटर्न। – Aron

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