गैर- OK प्रतिक्रिया के लिए IHttpActionResult के साथ सामग्री वापस करें


184

वेब एपीआई 2 नियंत्रक से लौटने के लिए, मैं प्रतिक्रिया के साथ सामग्री वापस कर सकता हूं यदि प्रतिक्रिया ठीक है (स्थिति 200) इस तरह:

    public IHttpActionResult Get()
    {
        string myResult = ...
        return Ok(myResult);
    }

यदि संभव हो तो, मैं जब संभव हो तो अंतर्निहित परिणाम प्रकारों का उपयोग करना चाहता हूं: https://msdn.microsoft.com/en-us/library/system.web.http.results(v=vs.118).aspx

मेरा प्रश्न एक अन्य प्रकार की प्रतिक्रिया के लिए है (200 नहीं), मैं इसके साथ एक संदेश (स्ट्रिंग) कैसे वापस कर सकता हूं? उदाहरण के लिए, मैं यह कर सकता हूं:

    public IHttpActionResult Get()
    {
       return InternalServerError();
    }

लेकिन यह नहीं:

    public IHttpActionResult Get()
    {
       return InternalServerError("Message describing the error here");
    }

आदर्श रूप से मैं चाहता हूं कि इसे सामान्यीकृत किया जाए ताकि मैं IHttpActionResult के किसी भी कार्यान्वयन के साथ एक संदेश वापस भेज सकूं।

क्या मुझे ऐसा करने की आवश्यकता है (और अपनी प्रतिक्रिया संदेश का निर्माण):

    public IHttpActionResult Get()
    {
       HttpResponseMessage responseMessage = ...
       return ResponseMessage(responseMessage);
    }

या कोई बेहतर तरीका है?


इसके बारे में कैसे: stackoverflow.com/questions/10732644/…
मिलन

क्या आप ApiController.InternalServerError msdn.microsoft.com/en-us/library/dn292630(v=vs.118).aspx
Ric

@Milen, धन्यवाद। ऐसा कुछ काम कर सकता है। मुझे जो पसंद नहीं है वह यह है कि प्रत्येक मौजूदा कार्यान्वयन के लिए एक अलग IHttpActionResult कार्यान्वयन बनाने की आवश्यकता है जिसका मैं उपयोग करने में सक्षम होना चाहता हूं।
मायाबेले

@Ric, नहीं, पैरामीटर एक अपवाद है। मैं एक संदेश को एक स्ट्रिंग के रूप में सेट करना चाहता हूं। इसके अलावा, यह अधिक सामान्य मामले को संबोधित नहीं करता है जहां कोड जरूरी आंतरिक सर्वर त्रुटि नहीं हो सकता है।
मायाबेले

3
@ मयबेल: क्या आपने शमिल यकूपोव का जवाब देखा? यह बहुत सरल और संक्षिप्त है कि स्वीकृत उत्तर।
इसहाक

जवाबों:


419

आप इसका उपयोग कर सकते हैं:

return Content(HttpStatusCode.BadRequest, "Any object");

1
लघु और सरल उपाय। अधिक कोड होने का मतलब अधिक बग और समय लेने वाली रखरखाव है।
थॉमस .बेंज़

6
जब यह कोशिश कर रहा हो, तो code(जहाँ कोड एक स्ट्रिंग है) का लौटा हुआ मान return Content(HttpStatusCode.OK, code)इनकैप्सुलेटेड है "जो कि अप्रत्याशित है, क्या इसका कोई कारण है? उदाहरण के लिए जो मान लौटा है, "\"value\""मैं mvc5 का उपयोग कर रहा हूँ
Deza

2
यदि आपको ApiController वर्ग के बाहर से ऐसा करने की आवश्यकता है, तो आप उपयोग कर सकते हैं: नया NegotiatedContentResult <T> (कोड, नया T (...), नियंत्रक)
लौटाएँ

क्या मैं इसे क्लास लाइब्रेरी से वापस कर सकता हूं? मुझे संदर्भ के लिए क्या चाहिए?
टूलकिट

54

आप HttpRequestMessagesExtensions.CreateErrorResponse ( System.Net.Httpनाम स्थान) का उपयोग कर सकते हैं , जैसे:

public IHttpActionResult Get()
{
   return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Message describing the error here"));
}

वेब एपीआई की सामग्री बातचीत का लाभ उठाने के अनुरोध के आधार पर प्रतिक्रियाएं बनाना बेहतर है।


6
Request.CreateErrorResponse एक HttpResponseMessage देता है, IHttpActionResult नहीं। आप जो वर्णन करते हैं वह एक HttpResponseMessage बनाने के लिए अच्छा अभ्यास है, लेकिन मेरे प्रश्न को संबोधित नहीं करता है। फिर भी धन्यवाद!
मायाबेले

@mayabelle आप IHttpActionResult को कंक्रीट बना सकते हैं और उन कोड को इस तरह से लपेट सकते हैं:
Quoc Nguyen

1
यह मेरे लिए काम करता है लेकिन मैंने Request.CreateResponse का उपयोग किया है ताकि त्रुटि संदेश कुंजी के बजाय एक स्ट्रिंग के रूप में दिखाई दे।
केमिस्ट

मुझे एक त्रुटि मिल रही है, स्निपेट विफल हो रहा है। यह कहता है कि 'अनुरोध' शून्य है। मैं Request.CreateResponse @ user1620220
शीना अग्रवाल

@SheenaAgrawal इस कोड को केवल एक HTTP अनुरोध के संदर्भ में निष्पादित किया जा सकता है। यदि ApiController.Requestयह शून्य है तो इसका मतलब है कि आप सही संदर्भ में नहीं हैं, या आपके WebAPI आर्किटेक्चर में कुछ टूट गया है।
user1620220

35

मैंने निम्नलिखित समाधान के साथ जाना समाप्त किया:

public class HttpActionResult : IHttpActionResult
{
    private readonly string _message;
    private readonly HttpStatusCode _statusCode;

    public HttpActionResult(HttpStatusCode statusCode, string message)
    {
        _statusCode = statusCode;
        _message = message;
    }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        HttpResponseMessage response = new HttpResponseMessage(_statusCode)
        {
            Content = new StringContent(_message)
        };
        return Task.FromResult(response);
    }
}

... जो इस तरह इस्तेमाल किया जा सकता है:

public IHttpActionResult Get()
{
   return new HttpActionResult(HttpStatusCode.InternalServerError, "error message"); // can use any HTTP status code
}

मैं सुधार के लिए सुझावों के लिए तैयार हूं। :)


1
शमिल यकूपोव का जवाब सबसे अच्छा जवाब है लेकिन केवल एपीकंट्रोलर वर्ग के अंदर से - इसे फिर से लिखना होगा जैसे कि "रिटर्न न्यू नेगोशिएटेड कॉन्टेंटइंड्टूल्ट <टी> (कोड, नया टी (...), कंट्रोलर)" को बाहर से इस्तेमाल किया जाए। नियंत्रक वर्ग। उस मामले में इस तरह के एक समाधान के रूप में ऊपर एक और अधिक पठनीय हो सकता है।
इथेरन

16

आप भी कर सकते हैं:

return InternalServerError(new Exception("SOME CUSTOM MESSAGE"));

1
हां, लेकिन इसका दर्द उस संदेश पाठ को वापस पाने के लिए है
उपयोगकर्ता

7

जो कोई भी किसी भी स्थिति में लौटने के साथ ResponseMessage के साथ लौटने में दिलचस्पी रखता है:

//CreateResponse(HttpStatusCode, T value)
return ResponseMessage(Request.CreateResponse(HttpStatusCode.XX, object));

7

ASP.NET वेब API 2 में, आप किसी भी ResponseMessageResultResponseMessage में लपेट सकते हैं :

public IHttpActionResult Get()
{
   HttpResponseMessage responseMessage = ...
   return new ResponseMessageResult(responseMessage);
}

कुछ मामलों में यह वांछित परिणाम प्राप्त करने का सबसे सरल तरीका हो सकता है, हालांकि आम तौर पर System.Web.Http.Results में विभिन्न परिणामों का उपयोग करना बेहतर हो सकता है ।


6

सरल:

return ResponseMessage(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Your message"));

याद रखना System.Net.Http और System.Net को संदर्भ दें ।


2

मैं इस पोस्ट को पढ़ने की सलाह दूंगा। सुझाव के अनुसार मौजूदा HttpResponse का उपयोग करने के कई तरीके हैं, लेकिन यदि आप वेब एपि 2 का लाभ लेना चाहते हैं, तो कुछ अंतर्निहित IHttpActionResult विकल्पों का उपयोग करके देखें

return Ok() 

या

return NotFound()

वेब एपि कंट्रोलर्स के लिए राइट रिटर्न टाइप चुनें


2

C # में परिभाषित HTTP कोड के समर्थन के साथ एक अधिक विस्तृत उदाहरण HttpStatusCode

public class MyController : ApiController
{
    public IHttpActionResult Get()
    {
        HttpStatusCode codeNotDefined = (HttpStatusCode)429;
        return Content(codeNotDefined, "message to be sent in response body");
    }
}

Contentअमूर्त वर्ग में परिभाषित एक आभासी विधि है ApiController, जो नियंत्रक का आधार है। नीचे के रूप में घोषणा देखें:

protected internal virtual NegotiatedContentResult<T> Content<T>(HttpStatusCode statusCode, T value);

1

@mayabelle आप IHttpActionResult को कंक्रीट बना सकते हैं और उन कोड को इस तरह से लपेट सकते हैं:

public class NotFoundPlainTextActionResult : IHttpActionResult
{
    public NotFoundPlainTextActionResult(HttpRequestMessage request, string message)
    {
        Request = request;
        Message = message;
    }

    public string Message { get; private set; }
    public HttpRequestMessage Request { get; private set; }

    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(ExecuteResult());
    }

    public HttpResponseMessage ExecuteResult()
    {
        var response = new HttpResponseMessage();

        if (!string.IsNullOrWhiteSpace(Message))
            //response.Content = new StringContent(Message);
            response = Request.CreateErrorResponse(HttpStatusCode.NotFound, new Exception(Message));

        response.RequestMessage = Request;
        return response;
    }
}

0

मुझे भी यही समस्या थी। मैं अपने एपीआई नियंत्रकों के लिए कस्टम परिणाम बनाना चाहता हूं, उन्हें कॉल करने के लिए return Ok("some text");

तब मैंने ऐसा किया: 1) सिंगलेटोन के साथ कस्टम परिणाम प्रकार बनाएं

public sealed class EmptyResult : IHttpActionResult
{
    public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
    {
        return Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.NoContent) { Content = new StringContent("Empty result") });
    }
}

2) नई विधि के साथ कस्टम नियंत्रक बनाएँ:

public class CustomApiController : ApiController
{
    public IHttpActionResult EmptyResult()
    {
        return new EmptyResult();
    }
}

और फिर मैं उन्हें अपने नियंत्रकों में इस तरह बुला सकता हूं:

public IHttpActionResult SomeMethod()
    {
       return EmptyResult();
    }

0

यह उत्तर स्ट्रिंग के बजाय वास्तविक वस्तु के साथ शमिल यकूपोव उत्तर पर आधारित है।

using System.Dynamic;

dynamic response = new ExpandoObject();
response.message = "Email address already exist";

return Content<object>(HttpStatusCode.BadRequest, response);

1
सामग्री <T> बहुत उपयोगी है
LastTribunal

0

अपवादों के लिए, मैं आमतौर पर करता हूं

 catch (Exception ex)
        {
            return InternalServerError(new ApplicationException("Something went wrong in this request. internal exception: " + ex.Message));
        }

0

उपरोक्त बातें वास्तव में सहायक हैं।

वेब सेवाओं का निर्माण करते समय, यदि आप सेवाओं का मामला लेंगे, तो उपभोक्ता बहुत सराहना करेंगे। मैंने आउटपुट की एकरूपता बनाए रखने की कोशिश की। इसके अलावा, आप टिप्पणी या वास्तविक त्रुटि संदेश दे सकते हैं। वेब सेवा उपभोक्ता केवल IsSuccess की जाँच कर सकता है या नहीं और सुनिश्चित करेगा कि समस्या है, और स्थिति के अनुसार कार्य करें।

  public class Response
    {
        /// <summary>
        /// Gets or sets a value indicating whether this instance is success.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance is success; otherwise, <c>false</c>.
        /// </value>
        public bool IsSuccess { get; set; } = false;

        /// <summary>
        /// Actual response if succeed 
        /// </summary>
        /// <value>
        /// Actual response if succeed 
        /// </value>
        public object Data { get; set; } = null;

        /// <summary>
        /// Remark if anythig to convey
        /// </summary>
        /// <value>
        /// Remark if anythig to convey
        /// </value>
        public string Remark { get; set; } = string.Empty;
        /// <summary>
        /// Gets or sets the error message.
        /// </summary>
        /// <value>
        /// The error message.
        /// </value>
        public object ErrorMessage { get; set; } = null;


    }  




[HttpGet]
        public IHttpActionResult Employees()
        {
            Response _res = new Response();
            try
            { 
                DalTest objDal = new DalTest(); 
                _res.Data = objDal.GetTestData();
                _res.IsSuccess = true;
                return Ok<Response>(_res);
            }
            catch (Exception ex)
            {
                _res.IsSuccess = false;
                _res.ErrorMessage = ex;
                return ResponseMessage(Request.CreateResponse(HttpStatusCode.InternalServerError, _res )); 
            } 
        }

यदि आपका कोई सुझाव है तो आपका स्वागत है


-1

देर से जवाब के लिए क्षमा करें आप सरल उपयोग क्यों नहीं करते हैं

return BadRequest("your message");

मैं इसे IHttpActionResultअपनी सभी त्रुटियों के लिए उपयोग करता हूं

यहाँ प्रलेखन है: https://msdn.microsoft.com/en-us/library/system.web.http.apicontroller.badrequest(v=vs.118).aspx


7
क्योंकि सभी त्रुटियां खराब अनुरोधों का परिणाम नहीं हैं, इसलिए एक 400प्रतिक्रिया अनुचित होगी। ओपी ने विशेष 500रूप से एक उदाहरण के रूप में प्रतिक्रिया दी ।
user1620220

हाँ, यह केवल BadRequest के साथ संभव है अन्य प्रकार एक संदेश तर्क नहीं लेते हैं
बेनराय
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.