ASP.NET कोर RC2 वेब एप से HTTP 500 कैसे लौटाएं?


188

RC1 में वापस, मैं यह करूंगा:

[HttpPost]
public IActionResult Post([FromBody]string something)
{    
    try{
        // ...
    }
    catch(Exception e)
    {
         return new HttpStatusCodeResult((int)HttpStatusCode.InternalServerError);
    }
}

RC2 में, अब HttpStatusCodeResult नहीं है, और ऐसा कुछ भी नहीं है जो मुझे पता चले कि मुझे 500 प्रकार के IActionResult लौटा सकता है।

क्या अब मैं जो पूछ रहा हूं उसके लिए दृष्टिकोण बिल्कुल अलग है? क्या अब हम Controllerकोड में प्रयास नहीं करते हैं ? क्या हम सिर्फ एपीआई कॉल करने के लिए एक सामान्य 500 अपवाद को फेंकने की रूपरेखा तैयार करते हैं? विकास के लिए, मैं सटीक अपवाद स्टैक कैसे देख सकता हूं?

जवाबों:


238

मैं जो देख सकता हूं उसमें ControllerBaseकक्षा के अंदर सहायक विधियां हैं । बस StatusCodeविधि का उपयोग करें :

[HttpPost]
public IActionResult Post([FromBody] string something)
{    
    //...
    try
    {
        DoSomething();
    }
    catch(Exception e)
    {
         LogException(e);
         return StatusCode(500);
    }
}

आप StatusCode(int statusCode, object value)ओवरलोड का उपयोग भी कर सकते हैं जो सामग्री पर भी बातचीत करता है।


7
ऐसा करने से, हम CORS हेडर खो देते हैं, इसलिए ब्राउज़र क्लाइंट से त्रुटियों को छिपाया जाता है। V निराशा होती है।
bbsimonbb

2
@bbsimonbb आंतरिक त्रुटियों को ग्राहकों से छिपाया जाना चाहिए। उन्हें डेवलपर्स के लिए लॉग इन किया जाना चाहिए।
हिमालय गर्ग

10
डेवलपर्स को पारंपरिक रूप से आनंद लेना चाहिए था, यह चुनने के लिए कि त्रुटि सूचना का स्तर किस स्तर पर वापस आया है।
bbsimonbb

177

यदि आप विशिष्ट संख्याओं को हार्डकोड नहीं करना चाहते हैं, तो आप अपनी प्रतिक्रिया का उपयोग Microsoft.AspNetCore.Mvc.ControllerBase.StatusCodeऔर निर्माण कर सकते हैं Microsoft.AspNetCore.Http.StatusCodes

return  StatusCode(StatusCodes.Status500InternalServerError);

अद्यतन: अगस्त 2019

शायद मूल प्रश्न से सीधे संबंधित नहीं है, लेकिन जब Microsoft Azure Functionsमैंने उसी परिणाम को प्राप्त करने की कोशिश की, तो मैंने पाया कि मुझे विधानसभा StatusCodeResultमें एक नई वस्तु का निर्माण करना था Microsoft.AspNetCore.Mvc.Core। मेरा कोड अब इस तरह दिखता है;

return new StatusCodeResult(StatusCodes.Status500InternalServerError);

11
महान एक, किसी भी हार्डकोड भागों / "मैजिक नंबर" से बचा जाता है। मैंने पहले भी StatusCode ((int) HttpStatusCode.InternalServerError) का उपयोग किया है, लेकिन मैंने आपका बेहतर उपयोग किया है।
अलेर

1
एक बात जिस पर मैंने समय पर विचार नहीं किया, वह यह है कि यह कोड को अधिक पठनीय बनाता है, इसके बारे में आपको पता है कि त्रुटि संख्या 500 किस से संबंधित है, यह कोड में वहीं है। सेल्फ डॉक्यूमेंटिंग :-)
एडवर्ड कोमेउ

11
मैं आंतरिक सर्वर त्रुटि (500) को कभी भी जल्द बदलने की कल्पना नहीं कर सकता।
रोल

2
बहुत बढ़िया। यह वास्तव में मेरे स्वैगर विशेषताओं को भी साफ करता है। पूर्व: [
प्रोडक्शंसस्पेन्सटाइप

43

यदि आपको अपनी प्रतिक्रिया में शरीर की आवश्यकता है, तो आप कॉल कर सकते हैं

return StatusCode(StatusCodes.Status500InternalServerError, responseObject);

यह प्रतिक्रिया वस्तु के साथ एक 500 लौटाएगा ...


3
यदि आप एक विशिष्ट प्रतिक्रिया ऑब्जेक्ट प्रकार नहीं बनाना चाहते हैं: return StatusCode(StatusCodes.Status500InternalServerError, new { message = "error occurred" });और निश्चित रूप से, आप एक संदेश के रूप में वर्णनात्मक रूप में जोड़ सकते हैं जैसे कि आप, और अन्य तत्व भी।
माइक टवेर्न

18

एक बेहतर तरीका अब तक इस संभाल करने के लिए (1.1) में यह करने के लिए है Startup.csकी Configure():

app.UseExceptionHandler("/Error");

इसके लिए मार्ग निष्पादित करेगा /Error। यह आपको आपके द्वारा लिखी गई प्रत्येक क्रिया में ट्राइ-कैच ब्लॉक जोड़ने से बचाएगा।

बेशक, आपको इसके समान एक ErrorController जोड़ने की आवश्यकता होगी:

[Route("[controller]")]
public class ErrorController : Controller
{
    [Route("")]
    [AllowAnonymous]
    public IActionResult Get()
    {
        return StatusCode(StatusCodes.Status500InternalServerError);
    }
}

अधिक जानकारी यहाँ


यदि आप वास्तविक अपवाद डेटा प्राप्त करना चाहते हैं, तो आप कथन के Get()ठीक पहले इसे ऊपर जोड़ सकते हैं return

// Get the details of the exception that occurred
var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();

if (exceptionFeature != null)
{
    // Get which route the exception occurred at
    string routeWhereExceptionOccurred = exceptionFeature.Path;

    // Get the exception that occurred
    Exception exceptionThatOccurred = exceptionFeature.Error;

    // TODO: Do something with the exception
    // Log it with Serilog?
    // Send an e-mail, text, fax, or carrier pidgeon?  Maybe all of the above?
    // Whatever you do, be careful to catch any exceptions, otherwise you'll end up with a blank page and throwing a 500
}

स्कॉट Sauber के ब्लॉग से लिया गया स्निपेट ऊपर ।


यह बहुत बढ़िया है, लेकिन मैं उस अपवाद को कैसे लॉग कर सकता हूं जिसे फेंक दिया गया था?
redwards510

@ redwards510 यहां बताया गया है कि आप इसे कैसे करते हैं: scottsauber.com/2017/04/03/… मैं इसे दर्शाने के लिए अपने उत्तर को अपडेट करूंगा, क्योंकि यह एक बहुत ही सामान्य उपयोग का मामला है
gldraphael

@gldraphael वर्तमान में हम Core 2.1 का उपयोग कर रहे हैं। स्कॉट का ब्लॉग बहुत अच्छा है, लेकिन मैं उत्सुक हूं अगर IExceptionHandlerPathFeature का उपयोग कर रहा हूं तो वर्तमान में अनुशंसित सर्वोत्तम अभ्यास हैं। शायद कस्टम मिडलवेयर बनाना बेहतर है?
पावेल

@ हम ExceptionHandlerयहां मिडलवेयर का उपयोग कर रहे हैं। आप निश्चित रूप से, अपना खुद का रोल कर सकते हैं या इसे बढ़ा सकते हैं जैसा कि आप फिट देखते हैं। यहां सूत्रों का लिंक है । EDIT: इस लाइन को देखेंIExceptionHandlerPathFeature
ग्रेलड्रेल

15
return StatusCode((int)HttpStatusCode.InternalServerError, e);

गैर-ASP.NET संदर्भों में उपयोग किया जाना चाहिए (ASP.NET कोर के लिए अन्य उत्तर देखें)।

HttpStatusCodeमें एक गणना है System.Net


11

कैसे के बारे में एक कस्टम ObjectResult वर्ग है कि एक के लिए एक आंतरिक सर्वर त्रुटि का प्रतिनिधित्व करता है OkObjectResult? आप अपने स्वयं के आधार वर्ग में एक सरल विधि रख सकते हैं ताकि आप आसानी से इंटरनलसर्वर उत्पन्न कर सकें और इसे उसी तरह वापस कर सकें जैसे आप Ok()या आप BadRequest()

[Route("api/[controller]")]
[ApiController]
public class MyController : MyControllerBase
{
    [HttpGet]
    [Route("{key}")]
    public IActionResult Get(int key)
    {
        try
        {
            //do something that fails
        }
        catch (Exception e)
        {
            LogException(e);
            return InternalServerError();
        }
    }
}

public class MyControllerBase : ControllerBase
{
    public InternalServerErrorObjectResult InternalServerError()
    {
        return new InternalServerErrorObjectResult();
    }

    public InternalServerErrorObjectResult InternalServerError(object value)
    {
        return new InternalServerErrorObjectResult(value);
    }
}

public class InternalServerErrorObjectResult : ObjectResult
{
    public InternalServerErrorObjectResult(object value) : base(value)
    {
        StatusCode = StatusCodes.Status500InternalServerError;
    }

    public InternalServerErrorObjectResult() : this(null)
    {
        StatusCode = StatusCodes.Status500InternalServerError;
    }
}

6

जब आप MVC .Net कोर में एक JSON प्रतिक्रिया वापस करना चाहते हैं तो आप भी उपयोग कर सकते हैं:

Response.StatusCode = (int)HttpStatusCode.InternalServerError;//Equals to HTTPResponse 500
return Json(new { responseText = "my error" });

यह JSON परिणाम और HTTPStatus दोनों लौटाएगा। मैं इसे jQuery.ajax () में परिणाम वापस करने के लिए उपयोग करता हूं।


1
मुझे उपयोग करना था return new JsonResult ...लेकिन अन्यथा महान काम किया।
माइक टावर्न

5

Aspnetcore-3.1 के लिए, आप Problem()नीचे की तरह भी उपयोग कर सकते हैं;

https://docs.microsoft.com/en-us/aspnet/core/web-api/handle-errors?view=aspnetcore-3.1

 [Route("/error-local-development")]
public IActionResult ErrorLocalDevelopment(
    [FromServices] IWebHostEnvironment webHostEnvironment)
{
    if (webHostEnvironment.EnvironmentName != "Development")
    {
        throw new InvalidOperationException(
            "This shouldn't be invoked in non-development environments.");
    }

    var context = HttpContext.Features.Get<IExceptionHandlerFeature>();

    return Problem(
        detail: context.Error.StackTrace,
        title: context.Error.Message);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.