Добавление кодов состояния Http в DynamicAPI и / или AbpApiController

#boilerplate #asp.net-boilerplate

#шаблон #asp.net-шаблон

Вопрос:

Я пытаюсь передать пользовательские коды состояния Http в заголовках ответов при использовании Asp.Net динамический API котельной плиты и веб-API написаны путем наследования AbpApiController.

Ниже приведены два способа, которые я пробовал, но потерпел неудачу: a) В AppService я использовал

 public async Task<HttpResponseMessage> GetData() 
{
    HttpResponseMessage response=new HttpResponseMessage();
    response.Headers.Add("Status", "201");
    return response;
}
  

б) Мой другой подход заключался в написании ApiController, который унаследовал AbpApiController. И в этом я написал

 public IHttpActionResult GetData()
{
     var data=null;
     return NotFoundResult(data);
 }
  

Оба этих подхода завершились неудачей. Как мы это реализуем?

Заранее спасибо 🙂

=======

Кроме того, как можно реализовать HostAuthenticationFilter(«Bearer») для AbpApiController?

Ответ №1:

Это обходной путь, который я придумал, когда столкнулся с той же проблемой. Решение больше связано с ASP.NET чем АБП.

Во-первых, я в своем базовом исключении создал поле для кода ошибки.

Что-то вроде этого :

 public class BaseException : Exception
{
    public int ErrorCode { get; private set; }
    public BaseException() : this(500)
    {

    }
    public BaseException(int errorCode)
    {
        ErrorCode = errorCode;
    }
    public BaseException(int errorCode, string message) : base(message)
    {
        ErrorCode = errorCode;
    }
}
  

Затем я ввел следующий модифицированный фильтр исключений, который распознает мои BaseException исключения и считывает код ошибки :

 namespace Abp.WebApi.ExceptionHandling
{
    /// <summary>
    /// Used to handle exceptions on web api controllers.
    /// </summary>
    public class CustomApiExceptionFilter : ExceptionFilterAttribute, ITransientDependency
    {
        /// <summary>
        /// Reference to the <see cref="ILogger"/>.
        /// </summary>
        public ILogger Logger { get; set; }

        /// <summary>
        /// Reference to the <see cref="IEventBus"/>.
        /// </summary>
        public IEventBus EventBus { get; set; }

        public IAbpSession AbpSession { get; set; }

        private readonly IAbpWebApiModuleConfiguration _configuration;

        /// <summary>
        /// Initializes a new instance of the <see cref="AbpApiExceptionFilterAttribute"/> class.
        /// </summary>
        public CustomApiExceptionFilter(IAbpWebApiModuleConfiguration configuration)
        {            
            _configuration = configuration;
            Logger = NullLogger.Instance;
            EventBus = NullEventBus.Instance;
            AbpSession = NullAbpSession.Instance;
        }

        /// <summary>
        /// Raises the exception event.
        /// </summary>
        /// <param name="context">The context for the action.</param>
        public override void OnException(HttpActionExecutedContext context)
        {
            var wrapResultAttribute = (context.ActionContext.ActionDescriptor)
                    .GetWrapResultAttributeOrNull();
            // ?? _configuration.DefaultWrapResultAttribute;

            if (wrapResultAttribute == null || wrapResultAttribute.LogError)
            {
                LogHelper.LogException(Logger, context.Exception);
            }

            if (wrapResultAttribute == null || wrapResultAttribute.WrapOnError)
            {
                context.Response = context.Request.CreateResponse(
                    GetStatusCode(context),
                    new AjaxResponse(
                        SingletonDependency<ErrorInfoBuilder>.Instance.BuildForException(context.Exception),
                        context.Exception is Abp.Authorization.AbpAuthorizationException)
                    );


                EventBus.Trigger(this, new AbpHandledExceptionData(context.Exception));
            }
        }

        private HttpStatusCode GetStatusCode(HttpActionExecutedContext context)
        {
            if (context.Exception is Abp.Authorization.AbpAuthorizationException)
            {
                return AbpSession.UserId.HasValue
                    ? HttpStatusCode.Forbidden
                    : HttpStatusCode.Unauthorized;
            }

            var customException = (context.Exception as BaseException);
            if (customException != null)
                return
                    (HttpStatusCode)customException.ErrorCode;

            return
               HttpStatusCode.InternalServerError;
        }
    }
}
  

Наконец, заменил автоматически зарегистрированный фильтр ABP моей реализацией в инициализации WebApiModule.

 public MyWebApiModule : AbpModule
{
    public override void Initialize()
    {
        // ...

        var filters = Configuration.Modules.AbpWebApi().HttpConfiguration.Filters;

        var exceptionFilter = filters.First(h => h.Instance is AbpExceptionFilterAttribute).Instance;
        filters.Remove(exceptionFilter);
        filters.Add(IocManager.Resolve<CustomApiExceptionFilter>());
    }
}
  

Теперь с помощью моих пользовательских исключений и фильтра я смог управлять кодами состояния ответа.