ASP.NET कोर वेब एपीआई अपवाद हैंडलिंग


280

मैं कई वर्षों से ASP.NET वेब API का नियमित उपयोग करने के बाद अपने नए REST API प्रोजेक्ट के लिए ASP.NET Core का उपयोग कर रहा हूँ। मुझे ASP.NET कोर वेब एपीआई में अपवादों को संभालने का कोई अच्छा तरीका नहीं दिखता है। मैंने फ़िल्टर / विशेषता को छोड़कर अपवाद को लागू करने का प्रयास किया:

public class ErrorHandlingFilter : ExceptionFilterAttribute
{
    public override void OnException(ExceptionContext context)
    {
        HandleExceptionAsync(context);
        context.ExceptionHandled = true;
    }

    private static void HandleExceptionAsync(ExceptionContext context)
    {
        var exception = context.Exception;

        if (exception is MyNotFoundException)
            SetExceptionResult(context, exception, HttpStatusCode.NotFound);
        else if (exception is MyUnauthorizedException)
            SetExceptionResult(context, exception, HttpStatusCode.Unauthorized);
        else if (exception is MyException)
            SetExceptionResult(context, exception, HttpStatusCode.BadRequest);
        else
            SetExceptionResult(context, exception, HttpStatusCode.InternalServerError);
    }

    private static void SetExceptionResult(
        ExceptionContext context, 
        Exception exception, 
        HttpStatusCode code)
    {
        context.Result = new JsonResult(new ApiResponse(exception))
        {
            StatusCode = (int)code
        };
    }
}

और यहाँ मेरा स्टार्टअप फ़िल्टर पंजीकरण है:

services.AddMvc(options =>
{
    options.Filters.Add(new AuthorizationFilter());
    options.Filters.Add(new ErrorHandlingFilter());
});

मुद्दा मैं यह है कि जब अपवाद में घटित होता है तो AuthorizationFilterयह मेरे द्वारा संभाला नहीं जा रहा है ErrorHandlingFilter। मैं यह उम्मीद कर रहा था कि इसे वहीं पकड़ा जाए जैसे कि यह पुराने ASP.NET वेब एपीआई के साथ काम करता है।

तो मैं एक्शन फिल्टर्स से सभी एप्लिकेशन अपवादों के साथ-साथ किसी भी अपवाद को कैसे पकड़ सकता हूं?


3
क्या आपने UseExceptionHandlerमिडलवेयर की कोशिश की है?
पावेल

मैं यहाँ एक उदाहरण है कि UseExceptionHandlerमिडिलवेयर का उपयोग कैसे करें
इल्या चेर्नोमोर्डिक

जवाबों:


538

एक्सेप्शन हैंडलिंग मिडिलवेयर

विभिन्न अपवाद हैंडलिंग दृष्टिकोणों के साथ कई प्रयोगों के बाद मैंने मिडलवेयर का उपयोग करके समाप्त किया। यह मेरे ASP.NET कोर वेब एपीआई अनुप्रयोग के लिए सबसे अच्छा काम किया। यह एप्लिकेशन अपवादों के साथ-साथ एक्शन फिल्टर के अपवादों को भी संभालता है और अपवाद हैंडलिंग और HTTP प्रतिक्रिया पर मेरा पूर्ण नियंत्रण है। यहाँ मेरा अपवाद है मिडलवेयर को हैंडल करना:

public class ErrorHandlingMiddleware
{
    private readonly RequestDelegate next;
    public ErrorHandlingMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            await HandleExceptionAsync(context, ex);
        }
    }

    private static Task HandleExceptionAsync(HttpContext context, Exception ex)
    {
        var code = HttpStatusCode.InternalServerError; // 500 if unexpected

        if      (ex is MyNotFoundException)     code = HttpStatusCode.NotFound;
        else if (ex is MyUnauthorizedException) code = HttpStatusCode.Unauthorized;
        else if (ex is MyException)             code = HttpStatusCode.BadRequest;

        var result = JsonConvert.SerializeObject(new { error = ex.Message });
        context.Response.ContentType = "application/json";
        context.Response.StatusCode = (int)code;
        return context.Response.WriteAsync(result);
    }
}

कक्षा में MVC से पहले इसे पंजीकृत करें Startup:

app.UseMiddleware(typeof(ErrorHandlingMiddleware));
app.UseMvc();

आप स्टैक ट्रेस, अपवाद प्रकार का नाम, त्रुटि कोड या इसके द्वारा इच्छित कुछ भी जोड़ सकते हैं। बहुत लचीला। यहाँ अपवाद प्रतिक्रिया का एक उदाहरण है:

{ "error": "Authentication token is not valid." }

जब आप सभी समापन बिंदुओं में बेहतर क्रमांकन स्थिरता के लिए ASP.NET MVC की क्रमांकन सेटिंग्स का उपयोग करने के लिए प्रतिक्रिया वस्तु को क्रमबद्ध करते हैं, तो इसका उपयोग IOptions<MvcJsonOptions>करने के लिए Invokeविधि पर इंजेक्शन लगाने पर विचार करें JsonConvert.SerializeObject(errorObj, opts.Value.SerializerSettings)

दृष्टिकोण २

एक और गैर-स्पष्ट एपीआई है जिसे UseExceptionHandlerसरल सुंदर के लिए "ओके" काम करता है:

app.UseExceptionHandler(a => a.Run(async context =>
{
    var feature = context.Features.Get<IExceptionHandlerPathFeature>();
    var exception = feature.Error;

    var result = JsonConvert.SerializeObject(new { error = exception.Message });
    context.Response.ContentType = "application/json";
    await context.Response.WriteAsync(result);
}));

यह अपवाद से निपटने के लिए एक बहुत स्पष्ट लेकिन आसान तरीका नहीं है। हालाँकि मैं अभी भी इस पर मिडिलवेयर दृष्टिकोण पसंद करता हूं क्योंकि मुझे आवश्यक निर्भरता को इंजेक्ट करने की क्षमता के साथ अधिक नियंत्रण मिलता है।


4
मैं आज काम करने के लिए एक कस्टम मिडलवेयर प्राप्त करने की कोशिश कर रहे डेस्क के खिलाफ अपना सिर पीट रहा हूं, और यह मूल रूप से उसी तरह काम करता है (मैं अनुरोध के लिए कार्य / लेनदेन की इकाई का प्रबंधन करने के लिए इसका उपयोग कर रहा हूं)। मुझे जो समस्या आ रही है, वह यह है कि 'अगली' में उठाए गए अपवाद मिडलवेयर में नहीं पकड़े गए हैं। जैसा कि आप कल्पना कर सकते हैं, यह समस्याग्रस्त है। मैं क्या गलत कर रहा हूं / गायब हूं? कोई संकेत या सुझाव?
brappleye3

5
@ brappleye3 - मुझे लगा कि समस्या क्या है। मैं अभी-अभी Startup.cs वर्ग में गलत स्थान पर मिडिलवेयर पंजीकृत कर रहा था। मैं app.UseMiddleware<ErrorHandlingMiddleware>();पहले ही चला गया app.UseStaticFiles();। अपवाद अब सही ढंग से पकड़ा गया लगता है। इससे मुझे विश्वास होता है कि app.UseDeveloperExceptionPage(); app.UseDatabaseErrorPage(); app.UseBrowserLink();मिडलवेयर ऑर्डर को सही करने के लिए कुछ आंतरिक जादू मिडलवेयर हैकरी करें।
जमादान

4
मैं मानता हूं कि कस्टम मिडलवेयर बहुत उपयोगी हो सकता है, लेकिन नोटफ़ाउंड, अनधिकृत और बैडर्सेस्ट स्थितियों के अपवादों का उपयोग करते हुए सवाल करेगा। बस स्टेटस कोड (NotFound () इत्यादि का उपयोग करके) सेट क्यों नहीं किया और फिर इसे अपने कस्टम मिडलवेयर में या UseStatusCodePagesWithReExecute के माध्यम से हैंडल करें? अधिक जानकारी के लिए devtrends.co.uk/blog/handling-errors-in-asp.net-core-web-api देखें
पॉल

4
यह बुरा है क्योंकि यह हमेशा JSON को क्रमबद्ध कर रहा है, पूरी तरह से सामग्री बातचीत की अनदेखी कर रहा है।
कोनराड

5
@ कोनराड मान्य बिंदु। इसलिए मैंने कहा कि यह उदाहरण वह है जहां आप शुरुआत कर सकते हैं, और अंतिम परिणाम नहीं। एपीआई के 99% के लिए JSON पर्याप्त से अधिक है। यदि आपको लगता है कि यह उत्तर पर्याप्त नहीं है, तो योगदान करने के लिए स्वतंत्र महसूस करें।
आंद्रेई

60

नवीनतम Asp.Net Core(कम से कम 2.2, शायद पहले) में एक अंतर्निहित मिडलवेयर है जो स्वीकृत उत्तर में कार्यान्वयन की तुलना में इसे थोड़ा आसान बनाता है:

app.UseExceptionHandler(a => a.Run(async context =>
{
    var exceptionHandlerPathFeature = context.Features.Get<IExceptionHandlerPathFeature>();
    var exception = exceptionHandlerPathFeature.Error;

    var result = JsonConvert.SerializeObject(new { error = exception.Message });
    context.Response.ContentType = "application/json";
    await context.Response.WriteAsync(result);
}));

यह बहुत ज्यादा एक ही करना चाहिए, लिखने के लिए बस थोड़ा कम कोड।

महत्वपूर्ण: आदेश से पहले इसे UseMvc(या UseRouting.Net कोर 3) में जोड़ना याद रखें ।


क्या यह DI को हैंडलर के लिए एक आर्ग के रूप में समर्थन करता है, या किसी को हैंडलर के भीतर सेवा लोकेटर पैटर्न का उपयोग करना होगा?
एलपी

32

आपका सबसे अच्छा शर्त यह है कि आप जिस लॉगिंग की तलाश कर रहे हैं उसे प्राप्त करने के लिए मिडलवेयर का उपयोग करें। आप अपने अपवाद लॉगिंग को एक मिडलवेयर में डालना चाहते हैं और फिर एक अलग मिडलवेयर में उपयोगकर्ता को प्रदर्शित किए गए अपने त्रुटि पृष्ठों को संभालते हैं। यह तर्क को अलग करने की अनुमति देता है और Microsoft द्वारा 2 मिडिलवेयर घटकों के साथ तैयार किए गए डिज़ाइन का अनुसरण करता है। यहाँ Microsoft के प्रलेखन की एक अच्छी कड़ी है: ASP.Net कोर में त्रुटि हैंडलिंग

अपने विशिष्ट उदाहरण के लिए, आप StatusCodePage मिडलवेयर में किसी एक एक्सटेंशन का उपयोग करना चाहते हैं या इस तरह अपना स्वयं का रोल कर सकते हैं ।

आप अपवादों को लॉग इन करने के लिए यहां एक उदाहरण पा सकते हैं: ExceptionHandlerMiddleware.cs

public void Configure(IApplicationBuilder app)
{
    // app.UseErrorPage(ErrorPageOptions.ShowAll);
    // app.UseStatusCodePages();
    // app.UseStatusCodePages(context => context.HttpContext.Response.SendAsync("Handler, status code: " + context.HttpContext.Response.StatusCode, "text/plain"));
    // app.UseStatusCodePages("text/plain", "Response, status code: {0}");
    // app.UseStatusCodePagesWithRedirects("~/errors/{0}");
    // app.UseStatusCodePagesWithRedirects("/base/errors/{0}");
    // app.UseStatusCodePages(builder => builder.UseWelcomePage());
    app.UseStatusCodePagesWithReExecute("/Errors/{0}");  // I use this version

    // Exception handling logging below
    app.UseExceptionHandler();
}

यदि आपको वह विशिष्ट कार्यान्वयन पसंद नहीं है, तो आप ईएलएम मिडलवेयर का उपयोग भी कर सकते हैं , और यहां कुछ उदाहरण दिए गए हैं: एल्म एक्सेप्शन मिडलवेयर

public void Configure(IApplicationBuilder app)
{
    app.UseStatusCodePagesWithReExecute("/Errors/{0}");
    // Exception handling logging below
    app.UseElmCapture();
    app.UseElmPage();
}

यदि वह आपकी आवश्यकताओं के लिए काम नहीं करता है, तो आप हमेशा अपने खुद के निर्माण के लिए अवधारणाओं को समझने के लिए ExceptionHandlerMiddleware और ElmMiddleware के उनके कार्यान्वयन को देखकर अपने खुद के मिडिलवेयर घटक को रोल कर सकते हैं।

यह महत्वपूर्ण है कि स्टेटसकोड नोड्स मिडलवेयर के नीचे, लेकिन आपके अन्य सभी मिडलवेयर घटकों के ऊपर अपवाद से निपटने वाले मिडलवेयर को जोड़ा जाए। इस तरह आपका अपवाद मिडलवेयर अपवाद को कैप्चर करेगा, उसे लॉग इन करेगा, फिर अनुरोध को StatusCodePage मिडलवेयर पर आगे बढ़ने की अनुमति देगा जो उपयोगकर्ता के लिए अनुकूल त्रुटि पृष्ठ प्रदर्शित करेगा।


आपका स्वागत है। मैंने किनारे के मामलों में डिफ़ॉल्ट UseStatusPages को ओवरराइड करने के लिए एक उदाहरण के लिए एक लिंक भी प्रदान किया है जो आपके अनुरोध को बेहतर ढंग से पूरा कर सकता है।
एशले ली

1
ध्यान दें कि एल्म लॉग को जारी नहीं रखता है, और इसे क्रमांकन प्रदान करने के लिए सेरिलॉग या एनएलग का उपयोग करने की सिफारिश की जाती है। देखें ईएलएम लॉग गायब हो जाते हैं। क्या हम इसे फाइल या डीबी के लिए जारी रख सकते हैं?
माइकल फ्रीजिम

2
लिंक अब टूट गया है।
मैथियास लिकेगार्ड लोरेनजेन

@AshleyLee, मेरा प्रश्न है कि UseStatusCodePagesवेब एपीआई सेवा कार्यान्वयन में उपयोग का है। कोई विचार या HTML बिल्कुल नहीं, केवल JSON प्रतिक्रियाएं ...
पॉल मिशैलिक

23

अच्छी तरह से स्वीकार किए गए उत्तर ने मुझे बहुत मदद की, लेकिन मैं रनटाइम पर त्रुटि स्थिति कोड का प्रबंधन करने के लिए अपने मिडलवेयर में HttpStatusCode पास करना चाहता था।

इस लिंक के अनुसार मुझे कुछ करने का विचार आया। इसलिए मैंने इसके साथ आंद्रेई उत्तर को मिला दिया। तो मेरा अंतिम कोड नीचे है:
1. बेस क्लास

public class ErrorDetails
{
    public int StatusCode { get; set; }
    public string Message { get; set; }

    public override string ToString()
    {
        return JsonConvert.SerializeObject(this);
    }
}

2. कस्टम अपवाद कक्षा प्रकार

 public class HttpStatusCodeException : Exception
{
    public HttpStatusCode StatusCode { get; set; }
    public string ContentType { get; set; } = @"text/plain";

    public HttpStatusCodeException(HttpStatusCode statusCode)
    {
        this.StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, string message) : base(message)
    {
        this.StatusCode = statusCode;
    }

    public HttpStatusCodeException(HttpStatusCode statusCode, Exception inner) : this(statusCode, inner.ToString()) { }

    public HttpStatusCodeException(HttpStatusCode statusCode, JObject errorObject) : this(statusCode, errorObject.ToString())
    {
        this.ContentType = @"application/json";
    }

}


3. कस्टम अपवाद मिडिलवेयर

public class CustomExceptionMiddleware
    {
        private readonly RequestDelegate next;

    public CustomExceptionMiddleware(RequestDelegate next)
    {
        this.next = next;
    }

    public async Task Invoke(HttpContext context /* other dependencies */)
    {
        try
        {
            await next(context);
        }
        catch (HttpStatusCodeException ex)
        {
            await HandleExceptionAsync(context, ex);
        }
        catch (Exception exceptionObj)
        {
            await HandleExceptionAsync(context, exceptionObj);
        }
    }

    private Task HandleExceptionAsync(HttpContext context, HttpStatusCodeException exception)
    {
        string result = null;
        context.Response.ContentType = "application/json";
        if (exception is HttpStatusCodeException)
        {
            result = new ErrorDetails() { Message = exception.Message, StatusCode = (int)exception.StatusCode }.ToString();
            context.Response.StatusCode = (int)exception.StatusCode;
        }
        else
        {
            result = new ErrorDetails() { Message = "Runtime Error", StatusCode = (int)HttpStatusCode.BadRequest }.ToString();
            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        }
        return context.Response.WriteAsync(result);
    }

    private Task HandleExceptionAsync(HttpContext context, Exception exception)
    {
        string result = new ErrorDetails() { Message = exception.Message, StatusCode = (int)HttpStatusCode.InternalServerError }.ToString();
        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
        return context.Response.WriteAsync(result);
    }
}


4. विस्तार विधि

public static void ConfigureCustomExceptionMiddleware(this IApplicationBuilder app)
    {
        app.UseMiddleware<CustomExceptionMiddleware>();
    }

5. स्टार्टअप में विधि कॉन्फ़िगर करें

app.ConfigureCustomExceptionMiddleware();
app.UseMvc();

अब खाता नियंत्रक में मेरा लॉगिन तरीका:

 try
        {
            IRepository<UserMaster> obj = new Repository<UserMaster>(_objHeaderCapture, Constants.Tables.UserMaster);
            var Result = obj.Get().AsQueryable().Where(sb => sb.EmailId.ToLower() == objData.UserName.ToLower() && sb.Password == objData.Password.ToEncrypt() && sb.Status == (int)StatusType.Active).FirstOrDefault();
            if (Result != null)//User Found
                return Result;
            else// Not Found
                throw new HttpStatusCodeException(HttpStatusCode.NotFound, "Please check username or password");
        }
        catch (Exception ex)
        {
            throw ex;
        }

ऊपर आप देख सकते हैं कि अगर मुझे उपयोगकर्ता नहीं मिला है तो HttpStatusCodeException को बढ़ाएं जिसमें मैंने HttpStatusCode.NotFound स्थिति और एक कस्टम संदेश पास किया है

पकड़ (HttpStatusCodeException पूर्व)

अवरुद्ध कहा जाएगा जो नियंत्रण को पारित करेगा

निजी टास्क हैंडलExceptionAsync (HttpContext संदर्भ, HttpStatusCodeException अपवाद) विधि




लेकिन क्या होगा अगर मुझे पहले रनटाइम त्रुटि मिली? उसके लिए मैंने ट्रायल कैच ब्लॉक का उपयोग किया है जो अपवाद को फेंक देता है और उसे कैच (अपवाद अपवाद ओ.बी.जे.) ब्लॉक में पकड़ लिया जाएगा और नियंत्रण को पास करेगा

टास्क हैंडलेक्सेप्शनएस्क्यू (HttpContext संदर्भ, अपवाद अपवाद)

तरीका।

मैंने एकरूपता के लिए एक एकल ErrorDetails वर्ग का उपयोग किया है।


विस्तार विधि कहाँ रखी जाए? दुर्भाग्य में startup.csमें void Configure(IapplicationBuilder app)मैं कोई त्रुटि मिलती है IApplicationBuilder does not contain a definition for ConfigureCustomExceptionMiddleware। और मैंने संदर्भ जोड़ा, कहां CustomExceptionMiddleware.csहै।
स्पेडो डी ला रॉसा

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

@ इनी, इस बारे में नहीं कह सकता ... लेकिन ऐसा लगता है कि आपको कभी भी किसी भी अपवाद को संभालने के लिए नहीं मिला है। महान काम
अर्जुन

19

प्रति अपवाद प्रकार के अपवाद हैंडलिंग व्यवहार को कॉन्फ़िगर करने के लिए आप NuGet पैकेज से Middleware का उपयोग कर सकते हैं:

कोड नमूना:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();

    services.AddExceptionHandlingPolicies(options =>
    {
        options.For<InitializationException>().Rethrow();

        options.For<SomeTransientException>().Retry(ro => ro.MaxRetryCount = 2).NextPolicy();

        options.For<SomeBadRequestException>()
        .Response(e => 400)
            .Headers((h, e) => h["X-MyCustomHeader"] = e.Message)
            .WithBody((req,sw, exception) =>
                {
                    byte[] array = Encoding.UTF8.GetBytes(exception.ToString());
                    return sw.WriteAsync(array, 0, array.Length);
                })
        .NextPolicy();

        // Ensure that all exception types are handled by adding handler for generic exception at the end.
        options.For<Exception>()
        .Log(lo =>
            {
                lo.EventIdFactory = (c, e) => new EventId(123, "UnhandlerException");
                lo.Category = (context, exception) => "MyCategory";
            })
        .Response(null, ResponseAlreadyStartedBehaviour.GoToNextHandler)
            .ClearCacheHeaders()
            .WithObjectResult((r, e) => new { msg = e.Message, path = r.Path })
        .Handled();
    });
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    app.UseExceptionHandlingPolicies();
    app.UseMvc();
}

16

सबसे पहले, आंद्रेई के लिए धन्यवाद क्योंकि मैंने उनके उदाहरण पर अपना समाधान आधारित किया है।

मैं इसमें शामिल हूं क्योंकि यह एक अधिक संपूर्ण नमूना है और पाठकों को कुछ समय बचा सकता है।

आंद्रेई के दृष्टिकोण की सीमा यह है कि लॉगिंग को संभालना संभव नहीं है, संभावित उपयोगी अनुरोध चर और सामग्री बातचीत को कैप्चर करना (यह हमेशा जेएसएन को लौटाएगा चाहे ग्राहक ने जो भी अनुरोध किया हो - XML ​​/ सादा पाठ आदि)।

मेरा दृष्टिकोण एक ObjectResult का उपयोग करना है जो हमें MVC में बेक किए गए कार्यक्षमता का उपयोग करने की अनुमति देता है।

यह कोड प्रतिक्रिया के कैशिंग को भी रोकता है।

त्रुटि प्रतिक्रिया को इस तरह से सजाया गया है कि इसे एक्सएमएल धारावाहिक द्वारा सीरियल किया जा सकता है।

public class ExceptionHandlerMiddleware
{
    private readonly RequestDelegate next;
    private readonly IActionResultExecutor<ObjectResult> executor;
    private readonly ILogger logger;
    private static readonly ActionDescriptor EmptyActionDescriptor = new ActionDescriptor();

    public ExceptionHandlerMiddleware(RequestDelegate next, IActionResultExecutor<ObjectResult> executor, ILoggerFactory loggerFactory)
    {
        this.next = next;
        this.executor = executor;
        logger = loggerFactory.CreateLogger<ExceptionHandlerMiddleware>();
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await next(context);
        }
        catch (Exception ex)
        {
            logger.LogError(ex, $"An unhandled exception has occurred while executing the request. Url: {context.Request.GetDisplayUrl()}. Request Data: " + GetRequestData(context));

            if (context.Response.HasStarted)
            {
                throw;
            }

            var routeData = context.GetRouteData() ?? new RouteData();

            ClearCacheHeaders(context.Response);

            var actionContext = new ActionContext(context, routeData, EmptyActionDescriptor);

            var result = new ObjectResult(new ErrorResponse("Error processing request. Server error."))
            {
                StatusCode = (int) HttpStatusCode.InternalServerError,
            };

            await executor.ExecuteAsync(actionContext, result);
        }
    }

    private static string GetRequestData(HttpContext context)
    {
        var sb = new StringBuilder();

        if (context.Request.HasFormContentType && context.Request.Form.Any())
        {
            sb.Append("Form variables:");
            foreach (var x in context.Request.Form)
            {
                sb.AppendFormat("Key={0}, Value={1}<br/>", x.Key, x.Value);
            }
        }

        sb.AppendLine("Method: " + context.Request.Method);

        return sb.ToString();
    }

    private static void ClearCacheHeaders(HttpResponse response)
    {
        response.Headers[HeaderNames.CacheControl] = "no-cache";
        response.Headers[HeaderNames.Pragma] = "no-cache";
        response.Headers[HeaderNames.Expires] = "-1";
        response.Headers.Remove(HeaderNames.ETag);
    }

    [DataContract(Name= "ErrorResponse")]
    public class ErrorResponse
    {
        [DataMember(Name = "Message")]
        public string Message { get; set; }

        public ErrorResponse(string message)
        {
            Message = message;
        }
    }
}

9

सबसे पहले, Startupवेब सर्वर से किसी भी त्रुटि के लिए त्रुटि पृष्ठ पर पुन: निष्पादित करने के लिए ASP.NET Core 2 को कॉन्फ़िगर करें और किसी भी अपवाद को छोड़ दें।

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment()) {
        // Debug config here...
    } else {
        app.UseStatusCodePagesWithReExecute("/Error");
        app.UseExceptionHandler("/Error");
    }
    // More config...
}

अगला, एक अपवाद प्रकार परिभाषित करें जो आपको HTTP स्थिति कोड के साथ त्रुटियों को फेंकने देगा।

public class HttpException : Exception
{
    public HttpException(HttpStatusCode statusCode) { StatusCode = statusCode; }
    public HttpStatusCode StatusCode { get; private set; }
}

अंत में, त्रुटि पृष्ठ के लिए आपके नियंत्रक में, त्रुटि के कारण के आधार पर प्रतिक्रिया को अनुकूलित करें और क्या प्रतिक्रिया सीधे अंतिम उपयोगकर्ता द्वारा देखी जाएगी। यह कोड मानता है कि सभी एपीआई URL शुरू होते हैं /api/

[AllowAnonymous]
public IActionResult Error()
{
    // Gets the status code from the exception or web server.
    var statusCode = HttpContext.Features.Get<IExceptionHandlerFeature>()?.Error is HttpException httpEx ?
        httpEx.StatusCode : (HttpStatusCode)Response.StatusCode;

    // For API errors, responds with just the status code (no page).
    if (HttpContext.Features.Get<IHttpRequestFeature>().RawTarget.StartsWith("/api/", StringComparison.Ordinal))
        return StatusCode((int)statusCode);

    // Creates a view model for a user-friendly error page.
    string text = null;
    switch (statusCode) {
        case HttpStatusCode.NotFound: text = "Page not found."; break;
        // Add more as desired.
    }
    return View("Error", new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, ErrorText = text });
}

ASP.NET Core आपके साथ डीबग करने के लिए त्रुटि विवरण को लॉग करेगा, इसलिए एक स्थिति कोड वह सब हो सकता है जो आप एक (संभावित रूप से अविश्वसनीय) आवश्यकताकर्ता को प्रदान करना चाहते हैं। यदि आप अधिक जानकारी दिखाना चाहते हैं, तो आप HttpExceptionइसे प्रदान कर सकते हैं । एपीआई त्रुटियों के लिए आप को बदल कर संदेश के मुख्य भाग में JSON एन्कोड त्रुटि की जानकारी रख सकते हैं return StatusCode...के साथ return Json...


0

मिडलवेयर या IExceptionHandlerPathFeature का उपयोग ठीक है। नाइयों में एक और तरीका है

एक अपवाद फ़ोल्डर बनाएं और इसे पंजीकृत करें

public class HttpGlobalExceptionFilter : IExceptionFilter
{
  public void OnException(ExceptionContext context)
  {...}
}
services.AddMvc(options =>
{
  options.Filters.Add(typeof(HttpGlobalExceptionFilter));
})
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.