c# एएसपी.नेट 5/एमवीसी 6 एचटीटीपीएक्सेप्शन के बराबर




.net asp.net-core (4)

एमवीसी 5 में आप एक एचटीटीपी कोड के साथ एक एचटीटीपी एक्सप्शन फेंक सकते हैं और इससे प्रतिक्रिया की तरह ही सेट हो जाएगा:

throw new HttpException((int)HttpStatusCode.BadRequest, "Bad Request.");

एचटीटीपीएक्सएप एएसपी.नेट 5 / एमवीसी 6 में मौजूद नहीं है। समकक्ष कोड क्या है?


Microsoft.AspNet.Mvc.Controller आधार वर्ग एक HttpBadRequest(string) ओवरलोड का पर्दाफाश करता है जो क्लाइंट पर लौटने के लिए एक त्रुटि संदेश लेता है। तो एक नियंत्रक कार्रवाई के भीतर से, आप कॉल कर सकते हैं:

return HttpBadRequest("Bad Request.");

आखिरकार मेरी नाक कहती है कि नियंत्रक कार्रवाई के भीतर से बुलाए गए किसी भी निजी पद्धति को पूर्णतः HTTP संदर्भ-अवगत होना चाहिए या एक IActionResult लौटा देना चाहिए या किसी अन्य छोटे कार्य को पूरी तरह से पृथक करना चाहिए, क्योंकि यह एक http पाइपलाइन के अंदर है। यह मेरी निजी राय है, लेकिन एक ऐसा वर्ग जो व्यवसाय तर्क के कुछ टुकड़े करता है, को HTTP स्थिति कोड नहीं लौटा देना चाहिए और इसके बजाय अपने अपवादों को फेंकना चाहिए जो नियंत्रक / कार्रवाई स्तर पर पकड़े और अनुवादित हो सकते हैं।


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

आप Boilerplate.AspNetCore Nuget पैकेज का उपयोग कर सकते हैं या आप निम्न ASP.NET MVC Boilerplate GitHub प्रोजेक्ट पर पूर्ण स्रोत कोड देख सकते हैं या ASP.NET MVC बॉयलरप्लेट प्रोजेक्ट टेम्पलेट का उपयोग करके एक नया प्रोजेक्ट बना सकते हैं जो आपको इस सुविधा को वैकल्पिक रूप से चालू कर देता है। जब कोई नया प्रोजेक्ट बनाते हैं (इसे चालू करने के लिए बस बॉक्स को चेक करें)

// Usage example in Startup.cs
public void Configure(IApplicationBuilder application)
{
    application.UseIISPlatformHandler();

    application.UseStatusCodePagesWithReExecute("/error/{0}");
    application.UseHttpException();

    application.UseMvc();
}

public static class ApplicationBuilderExtensions
{
    public static IApplicationBuilder UseHttpException(this IApplicationBuilder application)
    {
        return application.UseMiddleware<HttpExceptionMiddleware>();
    }
}

internal class HttpExceptionMiddleware
{
    private readonly RequestDelegate next;

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

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await this.next.Invoke(context);
        }
        catch (HttpException httpException)
        {
            context.Response.StatusCode = httpException.StatusCode;
            var responseFeature = context.Features.Get<IHttpResponseFeature>();
            responseFeature.ReasonPhrase = httpException.Message;
        }
    }
}

public class HttpException : Exception
{
    private readonly int httpStatusCode;

    public HttpException(int httpStatusCode)
    {
        this.httpStatusCode = httpStatusCode;
    }

    public HttpException(HttpStatusCode httpStatusCode)
    {
        this.httpStatusCode = (int)httpStatusCode;
    }

    public HttpException(int httpStatusCode, string message) : base(message)
    {
        this.httpStatusCode = httpStatusCode;
    }

    public HttpException(HttpStatusCode httpStatusCode, string message) : base(message)
    {
        this.httpStatusCode = (int)httpStatusCode;
    }

    public HttpException(int httpStatusCode, string message, Exception inner) : base(message, inner)
    {
        this.httpStatusCode = httpStatusCode;
    }

    public HttpException(HttpStatusCode httpStatusCode, string message, Exception inner) : base(message, inner)
    {
        this.httpStatusCode = (int)httpStatusCode;
    }

    public int StatusCode { get { return this.httpStatusCode; } }
}

वैकल्पिक रूप से, यदि आप एक मनमाना स्थिति कोड वापस करना चाहते हैं और अपवाद-आधारित दृष्टिकोण से संबंधित नहीं हैं, तो आप उपयोग कर सकते हैं

return new HttpStatusCodeResult(400);

अपडेट: .NET कोर आरसी 2 के रूप में, एचटीटीपी उपसर्ग को हटा दिया गया है। यह अभी है:

return new StatusCodeResult(400);

@ डीविडफॉवल के साथ संक्षिप्त बातचीत के बाद, ऐसा लगता है कि एएसपी.नेट 5 में एचटीटीपीएक्सेप्शन या एचटीटीपीआरपीएसपैक्स की कोई ऐसी धारणा नहीं है, जो कि "जादुई रूप से" जवाब संदेश को चालू करता है।

आप क्या कर सकते हैं, मध्यवर्ती के माध्यम से एएसपी.नेट 5 पाइपलाइन में हुक है , और जो आपके लिए अपवादों को संभालता है

यहां उनके त्रुटि हैंडलर मिडलवेयर के स्रोत कोड का एक उदाहरण है जो पाइप लाइन के ऊपर एक अपवाद के मामले में 500 की प्रतिक्रिया स्थिति कोड सेट करेगा:

public class ErrorHandlerMiddleware
{
    private readonly RequestDelegate _next;
    private readonly ErrorHandlerOptions _options;
    private readonly ILogger _logger;

    public ErrorHandlerMiddleware(RequestDelegate next, 
                                  ILoggerFactory loggerFactory,
                                  ErrorHandlerOptions options)
    {
        _next = next;
        _options = options;
        _logger = loggerFactory.CreateLogger<ErrorHandlerMiddleware>();
        if (_options.ErrorHandler == null)
        {
            _options.ErrorHandler = _next;
        }
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {
            await _next(context);
        }
        catch (Exception ex)
        {
            _logger.LogError("An unhandled exception has occurred: " + ex.Message, ex);

            if (context.Response.HasStarted)
            {
                _logger.LogWarning("The response has already started, 
                                    the error handler will not be executed.");
                throw;
            }

            PathString originalPath = context.Request.Path;
            if (_options.ErrorHandlingPath.HasValue)
            {
                context.Request.Path = _options.ErrorHandlingPath;
            }
            try
            {
                var errorHandlerFeature = new ErrorHandlerFeature()
                {
                    Error = ex,
                };
                context.SetFeature<IErrorHandlerFeature>(errorHandlerFeature);
                context.Response.StatusCode = 500;
                context.Response.Headers.Clear();

                await _options.ErrorHandler(context);
                return;
            }
            catch (Exception ex2)
            {
                _logger.LogError("An exception was thrown attempting
                                  to execute the error handler.", ex2);
            }
            finally
            {
                context.Request.Path = originalPath;
            }

            throw; // Re-throw the original if we couldn't handle it
        }
    }
}

और आपको इसे StartUp.cs साथ पंजीकृत करना StartUp.cs :

public class Startup
{
    public void Configure(IApplicationBuilder app, 
                          IHostingEnvironment env, 
                          ILoggerFactory loggerfactory)
    {
       app.UseMiddleWare<ExceptionHandlerMiddleware>();
    }
}




httpexception