मुझे HttpResponseMessage के बजाय IHttpActionResult का उपयोग क्यों करना चाहिए?


326

मैं WebApi के साथ विकास कर रहा हूं और WebApi2 पर चला गया हूं, जहां Microsoft ने एक नया IHttpActionResultइंटरफ़ेस पेश किया है, जो कि ए को वापस करने के लिए उपयोग किए जाने के लिए अनुशंसित लगता है HttpResponseMessage। मैं इस नए इंटरफ़ेस के फायदों पर भ्रमित हूं। यह मुख्य रूप से सिर्फ एक प्रदान करने के लिए लगता है थोड़ा एक बनाने के लिए आसान तरीका है HttpResponseMessage

मैं तर्क देता हूं कि यह "अमूर्तता के लिए अमूर्तता" है। क्या मैं कुछ भूल रहा हूँ? इस नए इंटरफ़ेस का उपयोग करने से मुझे वास्तविक विश्व के लिए क्या लाभ मिलेगा?

पुराना तरीका (WebApi):

public HttpResponseMessage Delete(int id)
{
    var status = _Repository.DeleteCustomer(id);
    if (status)
    {
        return new HttpResponseMessage(HttpStatusCode.OK);
    }
    else
    {
        throw new HttpResponseException(HttpStatusCode.NotFound);
    }
}

नया तरीका (WebApi2):

public IHttpActionResult Delete(int id)
{
    var status = _Repository.DeleteCustomer(id);
    if (status)
    {
        //return new HttpResponseMessage(HttpStatusCode.OK);
        return Ok();
    }
    else
    {
        //throw new HttpResponseException(HttpStatusCode.NotFound);
        return NotFound();
    }
}

मुझे बस कुछ दिलचस्प लगा। मुझे यकीन नहीं है कि ये परिणाम किसी और द्वारा सत्यापित किए जा सकते हैं। लेकिन मेरे द्वारा किए गए कुछ कॉल के साथ प्रदर्शन में बहुत सुधार हुआ: * एक उदाहरण के साथ HttpResponseMessageमैंने 9545 एमएस में प्रतिक्रिया वापस प्राप्त की । * IHttpActionResultमैं का उपयोग कर 294 एमएस में एक ही प्रतिक्रिया वापस मिल गया ।
क्रिस घाव

@chrislesage 9545 एमएस लगभग 10 सेकंड है। यहां तक ​​कि 294ms एक तरह से धीमा है। यदि आपके पास 100ms से अधिक लेने के लिए कुछ भी है तो कुछ और काम पर है। Ete से मिलने की तुलना में उस कहानी में और भी बहुत कुछ है।
एरोनल्स

जवाबों:


305

आप इसका उपयोग नहीं करने का निर्णय ले सकते हैं IHttpActionResultक्योंकि आपका मौजूदा कोड एक HttpResponseMessageऐसा निर्माण करता है जो डिब्बाबंद प्रतिक्रियाओं में से एक के लायक नहीं है। हालाँकि आप डिब्बाबंद प्रतिक्रिया का उपयोग करने के HttpResponseMessageलिए अनुकूलित कर सकते IHttpActionResultहैं ResponseMessage। मुझे यह पता लगाने में थोड़ा समय लगा, इसलिए मैं यह दिखाते हुए पोस्ट करना चाहता था कि आपको एक या दूसरे का चयन करने की आवश्यकता नहीं है:

public IHttpActionResult SomeAction()
{
   IHttpActionResult response;
   //we want a 303 with the ability to set location
   HttpResponseMessage responseMsg = new HttpResponseMessage(HttpStatusCode.RedirectMethod);
   responseMsg.Headers.Location = new Uri("http://customLocation.blah");
   response = ResponseMessage(responseMsg);
   return response;
}

ध्यान दें, ResponseMessageबेस क्लास की एक विधि है ApiControllerजो आपके कंट्रोलर को इनहेरिट करनी चाहिए।


1
मुझे यह जानने के लिए कुछ समय लगा कि ResponseMessage अब ResponseMessageResult है। शायद हाल ही में इसका नाम बदल दिया गया है? पुनश्च आपने उत्तर में एक नया कीवर्ड भी याद किया है और सुझाव के लिए बहुत बहुत धन्यवाद :)
इल्या चेर्नोमोर्डिक

10
@IlyaChernomordik ResponseMessageऔर ResponseMessageResultदो अलग चीजें हैं। ResponseMessage()एक विधि है , ApiControllerजिसमें से आपके नियंत्रक को विरासत में प्राप्त करना चाहिए, और इसलिए यह केवल एक विधि कॉल है। इसलिए newवहां किसी कीवर्ड की जरूरत नहीं है। आपको शायद विरासत में नहीं मिला है ApiControllerया आप एक स्थिर पद्धति के अंदर हैं। ResponseMessageResultकी वापसी प्रकार है ResponseMessage()
एरोनल्स

3
@IlyaChernomordik मैंने response = base.ResponseMessage(responseMsg)इसे और अधिक स्पष्ट करने के लिए लिखा हो सकता है कि यह बेस क्लास ApiController की एक विधि है
AaronLS

धन्यवाद, मेरे पास वास्तव में एक सेवा थी जो ApiController से विरासत में नहीं मिली थी, इसीलिए इसे खोजने में कुछ समय लगा।
इल्या चेर्नोमोर्डिक

3
@pootzko आप सही कह रहे हैं, मैंने इस तथ्य को संबोधित किया कि ओपी को लगा कि वे मानते थे कि दो दृष्टिकोण परस्पर अनन्य रूप से "पुराने तरीके" बनाम "नए तरीके" के रूप में हैं जब वास्तव में वे नहीं हैं। मुझे लगता है कि डारेल का उत्तर IHttpActionResult को वापस करने के कुछ लाभों को समझाने का एक अच्छा काम करता है, और मेरा उत्तर दर्शाता है कि आप पुराने HttpResponseMessage को IHttp.ctionResult में कैसे बदल सकते हैं ताकि आप दोनों दुनिया के सर्वश्रेष्ठ हो सकें।
एरोनल्स

84

आप अभी भी उपयोग कर सकते हैं HttpResponseMessage। वह क्षमता नहीं जाएगी। मैंने भी आपके साथ वैसा ही महसूस किया और टीम के साथ बड़े पैमाने पर तर्क दिया कि अतिरिक्त अमूर्तता की कोई आवश्यकता नहीं थी। कोशिश करने और अपने अस्तित्व को सही ठहराने के लिए कुछ तर्क दिए गए थे, लेकिन ऐसा कुछ भी नहीं था जिससे मुझे यकीन हो कि यह सार्थक था।

यही है, जब तक मैंने ब्रैड विल्सन से इस नमूने को देखा । यदि आप एक तरह से कक्षाओं का निर्माण करते हैं जिन्हें जंजीर बनाया जा सकता है, तो आप उत्पादन के लिए "एक्शन-लेवल" प्रतिक्रिया पाइपलाइन बनाने की क्षमता हासिल करते हैं । कवर के तहत, यह है कि कैसे लागू किया जाता है, हालांकि, कार्रवाई का तरीका पढ़ते समय उन लोगों का आदेश स्पष्ट नहीं होता है जो एक कारण है कि मैं एक्शन फ़िल्टर का प्रशंसक नहीं हूं।IHttpActionResultHttpResponseMessageActionFiltersActionFilters

हालाँकि, IHttpActionResultअपनी कार्रवाई पद्धति में स्पष्ट रूप से जंजीर बनाकर आप अपनी प्रतिक्रिया उत्पन्न करने के लिए सभी प्रकार के विभिन्न व्यवहारों की रचना कर सकते हैं।


62

यहाँ के कई लाभ हैं IHttpActionResultसे अधिक HttpResponseMessageमें उल्लेख किया है माइक्रोसॉफ्ट ASP.Net प्रलेखन :

  • आपके नियंत्रकों के परीक्षण इकाई को सरल करता है।
  • HTTP प्रतिक्रियाओं को अलग-अलग कक्षाओं में बनाने के लिए सामान्य तर्क को स्थानांतरित करता है।
  • प्रतिक्रिया के निर्माण के निम्न-स्तरीय विवरण को छिपाकर नियंत्रक कार्रवाई के इरादे को स्पष्ट करता है।

लेकिन यहाँ IHttpActionResultउल्लेख के लायक का उपयोग करने के कुछ अन्य फायदे हैं :

  • एकल जिम्मेदारी सिद्धांत का सम्मान : HTTP अनुरोधों की सेवा करने की जिम्मेदारी के लिए कार्य विधियों का कारण बनें और HTTP प्रतिक्रिया संदेशों को बनाने में उन्हें शामिल न करें।
  • उपयोगी कार्यान्वयन पहले से ही सिस्टम में परिभाषित किए गए हैं ।eb.Http.Results अर्थात्: Ok NotFound Exception Unauthorized BadRequest Conflict Redirect InvalidModelState( पूरी सूची के लिए लिंक )
  • डिफ़ॉल्ट रूप से Async और Await का उपयोग करता है ।
  • सिर्फ एग्जीक्यूटिंगExecuteAsync मेथड बनाकर आसान एक्शन
  • आप HttpResponseMessage को IHttpActionResult में परिवर्तितResponseMessageResult ResponseMessage(HttpResponseMessage response) करने के लिए उपयोग कर सकते हैं ।


18

यह सिर्फ मेरी निजी राय है और वेब एपीआई टीम के लोग शायद इसे बेहतर बता सकते हैं लेकिन यहां मेरा 2 सी है।

सबसे पहले, मुझे लगता है कि यह एक के ऊपर एक का सवाल नहीं है। आप दोनों क्या आप अपनी कार्रवाई विधि में क्या करना चाहते हैं पर लेकिन आदेश की वास्तविक शक्ति को समझने के लिए निर्भर करता है उनका उपयोग कर सकते IHttpActionResult, तो आप शायद उन लोगों के लिए सुविधाजनक सहायक तरीकों के बाहर कदम करने की आवश्यकता होगी ApiControllerके रूप में इस तरह के Ok, NotFoundआदि

असल में, मुझे लगता है कि IHttpActionResultएक कारखाने के रूप में लागू एक वर्ग HttpResponseMessage। उस मन सेट के साथ, यह अब एक वस्तु बन गई है जिसे वापस करने की आवश्यकता है और एक कारखाना जो इसे बनाता है। सामान्य प्रोग्रामिंग अर्थों में, आप कुछ निश्चित मामलों में और कुछ मामलों में वस्तु का निर्माण कर सकते हैं, ऐसा करने के लिए आपको एक कारखाने की आवश्यकता होती है। मुझे भी।

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

उपयोग करने का एक और फायदा IHttpActionResultरिटर्न प्रकार के रूप यह है कि यह MVC के समान ASP.NET वेब एपीआई एक्शन विधि बनाता है। मीडिया फॉर्मेटरों में पकड़े बिना आप कोई भी कार्रवाई परिणाम वापस कर सकते हैं।

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

लंबी कहानी छोटी - यह IHttpActionResultबनाम नहीं है HttpResponseMessage। असल में, यह है कि आप कैसे प्रतिक्रिया बनाना चाहते हैं। इसे स्वयं या किसी कारखाने के माध्यम से करें।


फैक्ट्री जस्टिफ़िकेशन के साथ मुझे जो समस्या थी वह यह है कि मैं आसानी से ResponseFactory.CreateOkResponse()उस HttpResponseMessage की तरह स्टैटिक तरीके बना सकता हूँ , और मुझे प्रतिक्रिया बनाते समय एसिंक्स स्टफ से निपटना नहीं था। एक टीम के सदस्य ने इस तथ्य का उल्लेख किया कि हेडर मूल्यों को उत्पन्न करने के लिए यदि आपको I / O करने की आवश्यकता है तो एसिंक्स उपयोगी हो सकता है। यह निश्चित नहीं है कि यह कितनी बार होता है।
डारेल मिलर

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

6

: वेब एपीआई मूल रूप से वस्तु के 4 प्रकार वापसी void, HttpResponseMessage, IHttpActionResult, और अन्य मजबूत प्रकार के। वेब एपीआई का पहला संस्करण, HttpResponseMessageजो सीधे HTTP प्रतिक्रिया संदेश के लिए बहुत आगे है।

IHttpActionResultवेबएपीआई जिनमें से 2 रैप की तरह है द्वारा शुरू की गई थी HttpResponseMessage। इसमें a ExecuteAsync()बनाने की विधि सम्‍मिलित है HttpResponseMessage। यह आपके नियंत्रक की इकाई परीक्षण को सरल करता है।

अन्य वापसी प्रकार वेब एपीआई द्वारा प्रतिक्रिया बॉडी में मीडिया फॉर्मेटर का उपयोग करके क्रमबद्ध रूप से मजबूत टाइप किए गए वर्ग हैं। दोष यह था कि आप 404 जैसे त्रुटि कोड को सीधे नहीं लौटा सकते। आप बस इतना कर सकते हैं कि एक HttpResponseExceptionत्रुटि है।


3

मैं बल्कि IHttpActionResult के लिए TaskExecuteAsync इंटरफ़ेस फ़ंक्शन लागू करूँगा। कुछ इस तरह:

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        var response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);

        switch ((Int32)_respContent.Code)
        { 
            case 1:
            case 6:
            case 7:
                response = _request.CreateResponse(HttpStatusCode.InternalServerError, _respContent);
                break;
            case 2:
            case 3:
            case 4:
                response = _request.CreateResponse(HttpStatusCode.BadRequest, _respContent);
                break;
        } 

        return Task.FromResult(response);
    }

, जहां _request HttpRequest है और _respContent पेलोड है।


2

हमारे पास उपयोग करने के निम्नलिखित लाभ IHttpActionResultहैं HttpResponseMessage:

  1. उपयोग करके IHttpActionResultहम केवल स्थिति कोड पर नहीं भेजे जाने के लिए डेटा पर ध्यान केंद्रित कर रहे हैं। तो यहां कोड क्लीनर होगा और बनाए रखना बहुत आसान होगा।
  2. कार्यान्वित नियंत्रक विधि की इकाई परीक्षण आसान हो जाएगा।
  3. डिफ़ॉल्ट रूप से उपयोग करता है asyncऔर await
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.