使用IResultFilter包装ASP.NET Core WebAPI方法的结果

时间:2017-11-02 11:09:17

标签: asp.net-core asp.net-core-mvc asp.net-core-webapi asp.net-core-2.0

我已经实现了这样的结果过滤器:

public class ResultWrapperFilter : IResultFilter
{
    public void OnResultExecuting(ResultExecutingContext context)
    {
        if (!(context.ActionDescriptor is ControllerActionDescriptor))
        {
            return;
        }

        var objectResult = context.Result as ObjectResult;
        if (objectResult == null)
        {
            return;
        }

        if (!(objectResult.Value is WrappedResponseBase))
        {
            objectResult.Value = new WrappedResponse(objectResult.Value);
        }
    }

    public void OnResultExecuted(ResultExecutedContext context)
    {
    }
}

通过配置MvcOptionsConfigureServices(IServiceCollection services)来使用过滤器:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<MvcOptions>(
            options => { options.Filters.AddService<ResultWrapperFilter>(); });
    services.AddMvc();

    // ... the rest is omitted for readability
}

我遇到的问题是此过滤器导致InvalidCastException:无法将类型为'WrappedResponse'的对象强制转换为'System.String'(有问题的方法将字符串作为返回值类型)。

我甚至允许使用IResultFilter执行此操作吗?

注意:我知道使用中间件来完成响应包装的可能性。我不想使用中间件来实现这一点,因为中间件无法访问context.Result as ObjectResult。从响应流反序列化,再次包装和序列化似乎是不必要的。

1 个答案:

答案 0 :(得分:0)

所以这是一个答案,它刚刚来到我身边。 设置objectResult.Value时,还需要设置objectResult.DeclaredType

所以在这种情况下:

if (!(objectResult.Value is WrappedResponseBase))
{
    objectResult.Value = new WrappedResponse(objectResult.Value);
    objectResult.DeclaredType = typeof(WrappedResponse);
}