【问题标题】:Format FilterAttribute result using Strategy Pattern in ASP.NET Core在 ASP.NET Core 中使用策略模式格式化 FilterAttribute 结果
【发布时间】:2020-04-11 15:17:13
【问题描述】:

我创建了一个操作过滤器,以使用context.resultActionFilterAttribute 中返回自定义结果:

public class ResultApi : ActionFilterAttribute
{
    private readonly ResposeFormat resposeFormat;

    public ResultApi(ResposeFormat resposeFormat)
    {
        this.resposeFormat = resposeFormat;
    }
    public override void OnResultExecuting(ResultExecutingContext context)
    {
        resposeFormat.ContextResult(context);
        base.OnResultExecuting(context);
    }
}

我正在使用策略模式来格式化结果:

public abstract class ResposeFormat
{
    public abstract void ContextResult(ResultExecutingContext context);
}

而且,这里是我的 Formatter 的不同实现:

确定结果:

public abstract class OkResultFormatter : ResposeFormat
{
    public override void ContextResult(ResultExecutingContext context)
    {
        if (context.Result is OkResult okResult)
            context.Result = new JsonResult(new ReturnResult(true, StatusCode.Success)) { StatusCode = okResult.StatusCode };
    }
}

错误请求结果:

public abstract class BadRquestObjectresultFormatter : ResposeFormat
{
    public override void ContextResult(ResultExecutingContext context)
    {
        if (context.Result is BadRequestObjectResult badRequestObjectResult)
        {
            var message = badRequestObjectResult.Value.ToString();
            if (badRequestObjectResult.Value is SerializableError errors)
            {
                var errorMessages = errors.SelectMany(p => (string[])p.Value).Distinct();
                message = string.Join(" | ", errorMessages);
            }
            context.Result = new JsonResult(new ReturnResult(false, StatusCode.BadRequest, message)) { StatusCode = badRequestObjectResult.StatusCode };
        }
    }
}

当我将context 传递给resposeFormat.ContextResult(context); 时,我希望它找到请求的类型并使用OkResultFormatterBadRquestObjectresultFormatter

我该怎么做?

【问题讨论】:

    标签: c# asp.net asp.net-core design-patterns


    【解决方案1】:

    你必须稍微改变一下。

    首先,您必须将抽象的get-only 属性添加到您的ResultTypeToFormat 以确定每个实现应处理的ObjectResult 类型:

    public abstract class ResponseFormatter
    {
        public abstract Type ResultTypeToFormat { get; }
    
        public abstract void ContextResult(ResultExecutingContext context);
    }
    

    因此,您必须更改如下实现:

    public class OkResultFormatter : ResponseFormatter
    {
        public override Type ResultTypeToFormat => typeof(OkObjectResult);
    
        public override void ContextResult(ResultExecutingContext context)
        {
            context.Result = new JsonResult(new ReturnResult(HttpStatusCode.OK));
        }
    }
    
    public class BadRequestResultFormatter : ResponseFormatter
    {
        public override Type ResultTypeToFormat => typeof(BadRequestObjectResult);
    
        public override void ContextResult(ResultExecutingContext context)
        {
            // Perform other bad request stuff here ...
            context.Result = new JsonResult(new ReturnResult(HttpStatusCode.BadRequest));
        }
    }
    

    通过这些更改,现在您必须像这样在 DI 容器中注册所有结果格式化程序:

    services.AddScoped<ResponseFormatter, OkResultFormatter>();
    services.AddScoped<ResponseFormatter, BadRequestResultFormatter>();
    

    最后,您可以在 Filter Attribute 中动态格式化结果:

    public class CustomResultFilterAttribute : ActionFilterAttribute
    {
        private readonly IEnumerable<ResponseFormatter> _responseFormatters;
    
        public CustomResultFilterAttribute(IEnumerable<ResponseFormatter> responseFormatters)
        {
            _responseFormatters = responseFormatters;
        }
    
        public override void OnResultExecuting(ResultExecutingContext context)
        {
            Type resultType = context.Result.GetType();
    
            ResponseFormatter appropriateFormatter = _responseFormatters
                .Single(formatter => formatter.ResultTypeToFormat == resultType);
    
            appropriateFormatter.ContextResult(context);
        }
    }
    

    这里也是 Github 中的示例项目:Sample project

    【讨论】:

      猜你喜欢
      • 2019-04-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-09
      • 2020-01-25
      • 2013-04-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多