La risposta ben accettata mi ha aiutato molto, ma volevo passare HttpStatusCode nel mio middleware per gestire il codice di stato dell'errore in fase di esecuzione.
Secondo questo link ho avuto l'idea di fare lo stesso. Quindi ho unito la risposta Andrei a questo. Quindi il mio codice finale è di seguito:
1. Classe di base
public class ErrorDetails
{
public int StatusCode { get; set; }
public string Message { get; set; }
public override string ToString()
{
return JsonConvert.SerializeObject(this);
}
}
2. Tipo di classe di eccezione personalizzata
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 di eccezione personalizzato
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. Metodo di estensione
public static void ConfigureCustomExceptionMiddleware(this IApplicationBuilder app)
{
app.UseMiddleware<CustomExceptionMiddleware>();
}
5. Configurare il metodo in startup.cs
app.ConfigureCustomExceptionMiddleware();
app.UseMvc();
Ora il mio metodo di accesso in Controller account:
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;
}
Sopra puoi vedere se non ho trovato l'utente quindi sollevare lo stato HttpStatusCodeException in cui ho passato lo stato HttpStatusCode.NotFound e un messaggio personalizzato
nel middleware
catch (HttpStatusCodeException ex)
verrà chiamato il blocco che passerà il controllo a
Attività privata HandleExceptionAsync (contesto HttpContext, eccezione HttpStatusCodeException)
.
E se avessi ricevuto un errore di runtime prima? Per questo ho usato provare a catturare il blocco che genera un'eccezione e verrà catturato nel blocco catch (Exception exceptionObj) e passerà il controllo a
Attività HandleExceptionAsync (contesto HttpContext, eccezione eccezione)
metodo.
Ho usato una singola classe ErrorDetails per l'uniformità.
UseExceptionHandler
middleware?