#c# #aop #webapi #postsharp
Вопрос:
Я пытаюсь использовать PostSharp в проекте WebAPI. Я не могу сосредоточиться на этой задаче. Я хотел бы использовать контракты PostSharp для проверки входящих DTO и централизованной обработки исключений в случае ошибки проверки. Но я не знаю, как применить аспект исключения на уровне класса, и, что еще хуже, как вернуть ответ на ошибку JSON, когда это произойдет.
Комментарии:
1. Над какой платформой вы работаете? ASP.NET Ядро? У вас есть примеры кода, от которых вы пытаетесь избавиться (как выглядит ваш текущий подход?)? Вы просмотрели документацию и примеры перехвата вызовов методов ?
2. Платформа-.NET 5.0. У меня есть контроллер, для которого я хочу проверить входные данные. Для этого я использовал контракты PostSharp, и создаются исключения для недопустимых запросов. Просто, похоже, не удается поймать ни одного, потому что фактическое исключение создается в установщике класса DTO запроса, который создается в методе контроллера атрибутом [FromBody].
3. Обработка исключения в методе контроллера не работает, так как исключение создается до того, как будет создан метод контроллера. Найдите «исключение привязки модели дескриптора .net core», чтобы найти способ подключиться к этому процессу.
Ответ №1:
Без примеров кода немного неясно, для чего вы пытаетесь использовать PostSharp. Похоже, вы ищете какую-то типичную проверку модели в ASP.NET Ядро (.NET 5) и возврат пользовательского ответа JSON (при условии, что вы работаете с ASP.NET веб-API).
Я знаю, что вы спрашиваете о PostSharp, но я считаю, что для этого требуется некоторый пользовательский код, чтобы он работал и возвращал пользовательские ответы в ASP.NET, в то время как вы получаете большую часть этого бесплатно с помощью самого ASP в пространстве имен DataAnnotations.
Пример:
// CredentialsRequest.cs
using System.ComponentModel.DataAnnotations;
public class Credentials
{
[Required]
[EmailAddress]
public string Email { get; set; }
[Required]
public string Password { get; set; }
}
// AuthenticationController.cs
[ApiController]
public class AuthenticationController : ControllerBase
{
[HttpPost]
public Task<IActionResult> Login([FromBody] Credentials credentials)
{
var result = // check `credentials` for valid login
return result.Success
? Ok(result)
: StatusCode(StatusCodes.Status401Unauthorized, result);
}
}
Чтобы отловить все ошибки проверки модели, вы можете добавить следующую фабрику ответов Startup.ConfigureServices
(настройте ее по своему усмотрению).:
services.Configure<ApiBehaviorOptions>(config =>
{
// Override default response when input model is invalid
config.InvalidModelStateResponseFactory =
ctx => new BadRequestObjectResult(new BaseResponse(
success: ctx.ModelState.IsValid,
errors: ctx.ModelState.Values
.Where(v => v.ValidationState == ModelValidationState.Invalid)
.SelectMany(v => v.Errors)
.Select(e => new ErrorDetails
{
Code = "ModelError",
Description = e.ErrorMessage
})
.ToList()
));
});
Вот BaseResponse
и ErrorDetails
некоторые простые модели данных/классы, которые я использую в качестве основы для всех моих моделей данных ответов:
public class BaseResponse
{
public bool Success { get; }
public List<ErrorDetails> Errors { get; }
public BaseResponse(bool success, ErrorDetails error)
: this(success, new List<ErrorDetails> { error })
{ }
public BaseResponse(bool success, List<ErrorDetails> errors = null)
{
Success = success;
Errors = errors;
}
}
Если вы не настроили свой API для возврата данных в другом формате, по умолчанию это должен быть JSON.
Комментарии:
1. Спасибо @Xerillio за этот подробный пример. Я знаю о датааннотациях, и это именно то, что мне нужно, я просто попытался использовать PostSharp. Шаблоны. Вместо этого заключаются контракты.