คำตอบที่ได้รับการยอมรับเป็นอย่างดีช่วยฉันได้มาก แต่ฉันต้องการส่ง HttpStatusCode ในมิดเดิลแวร์ของฉันเพื่อจัดการรหัสสถานะข้อผิดพลาดที่รันไทม์
ตามลิงค์นี้ฉันมีความคิดที่จะทำเช่นเดียวกัน ดังนั้นฉันจึงรวมคำตอบ Andrei เข้ากับสิ่งนี้ ดังนั้นรหัสสุดท้ายของฉันอยู่ด้านล่าง:
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. Middleware Exception ที่กำหนดเอง
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. กำหนดค่าวิธีการใน startup.cs
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 และข้อความที่กำหนดเอง
ในมิดเดิลแวร์
catch (HttpStatusCodeException ex)
บล็อกจะถูกเรียกซึ่งจะผ่านการควบคุมไป
Private Task HandleExceptionAsync (บริบท HttpContext, ข้อยกเว้น HttpStatusCodeException)
.
แต่ถ้าฉันมีข้อผิดพลาด runtime มาก่อน เพื่อที่ฉันได้ใช้ลอง catch catch ซึ่งข้อยกเว้นการโยนและจะถูกจับใน catch (Exception exceptionObj) บล็อกและจะผ่านการควบคุมไป
Task HandleExceptionAsync (บริบท HttpContext, ข้อยกเว้น)
วิธี.
ฉันใช้คลาส ErrorDetails เดียวเพื่อความสม่ำเสมอ
UseExceptionHandler
มิดเดิลแวร์แล้วหรือยัง