1

当使用 Asp.Net 样板动态 API 和通过继承 AbpApiController 编写的 web api 时,我试图在响应标头中传递自定义 Http 状态代码。

以下是我尝试过的两种方法,但都失败了:a)在AppService中,我使用了

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

b) 我的另一种方法是编写一个继承 AbpApiController 的 ApiController。在那,我写了

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

这两种方法都失败了。我们如何实现这一点?

提前致谢 :-)

=======

另外,如何为 AbpApiController 实现 HostAuthenticationFilter("Bearer")?

4

1 回答 1

1

这是我遇到相同问题时提出的解决方法。解决方案与 ASP.NET 比 ABP 更相关。

首先,我在我的基本异常中为错误代码创建了字段。

像这样的东西:

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;
        }
    }
}

最后,用我在 WebApiModule 初始化中的实现替换了ABP 自动注册过滤器。

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>());
    }
}

现在通过我的自定义异常和过滤器,我能够控制响应状态代码。

于 2016-11-28T13:06:24.417 回答