Asp. NET обработка ошибок атрибута пользовательской модели ядра 3 - PullRequest
0 голосов
/ 10 января 2020

Мне нужно поймать исключение из моего пользовательского атрибута модели при его проверке. Вот мой HttpStatusCodeExceptionMiddleware:

public class HttpStatusCodeExceptionMiddleware
    {
        private readonly RequestDelegate _next;

        public HttpStatusCodeExceptionMiddleware(RequestDelegate next)
        {
            _next = next ?? throw new ArgumentNullException(nameof(next));
        }

        public async Task Invoke(HttpContext context)
        {
            try
            {
                await _next(context);
            }
            catch (HttpStatusCodeException ex)
            {
                if (context.Response.HasStarted)
                {
                    throw;
                }

                context.Response.Clear(); //<-possible Angular CORS error
                context.Response.StatusCode = ex.StatusCode;
                context.Response.ContentType = ex.ContentType;

                ProblemDetails responseBody = new ProblemDetails(ex.Message, ex.StatusCode, "Request error", ex.Key);
                await context.Response.WriteAsync(JsonConvert.SerializeObject(responseBody));

                return;
            }
        }

public class HttpStatusCodeException : Exception
    {
        public int StatusCode { get; set; }
        public string ContentType { get; set; } = @"text/plain";
        //key for translation
        public string Key { get; set; }

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

        public HttpStatusCodeException(HttpResponseType statusCode, string message, string key) : base(message)
        {
            StatusCode = (int)statusCode;
            Key = key;
        }

        public HttpStatusCodeException(HttpResponseType statusCode, Exception inner, string key) : base(inner.ToString())
        {
            Key = key;
        }

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

public static class HttpStatusCodeExceptionMiddlewareExtensions
    {
        public static IApplicationBuilder UseHttpStatusCodeExceptionMiddleware(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<HttpStatusCodeExceptionMiddleware>();
        }
    }

И я использую его в методе Startup.cs Configure следующим образом:

app.UseHttpStatusCodeExceptionMiddleware();

Но в этом сценарии мне нужно поймать проверку атрибута модели исключение, но мое решение ловит только исключения контроллера. Есть ли способ сделать это?

thnx

1 Ответ

0 голосов
/ 13 января 2020

Вам нужно бросить HttpStatusCodeException, тогда вы можете нажать catch (HttpStatusCodeException ex):

1. Атрибут подтверждения:

public class TestNameAttribute : ValidationAttribute
{
    protected override ValidationResult IsValid(object value,
        ValidationContext validationContext)
    {       
        if (value.ToString().StartsWith("a"))
        {
            throw new HttpStatusCodeException(HttpStatusCode.BadRequest, "Name could not start with a", value.ToString());
            //return new ValidationResult("Name could not start with a");
        }
        return ValidationResult.Success;
    }
}

2.Модель:

public class YourModel
{

    public long Id { get; set; }
    [TestName]
    public string Name { get; set; }
    public string DisplayName { get; set; }
}

3.Тестовое действие:

[HttpPost]
public async Task<ActionResult<Mood>> Post(YourModel model)
{
    _context.YourModel.Add(model);
    await _context.SaveChangesAsync();

    return CreatedAtAction("Get", new { id = model.Id }, model);
}
...