C# - 如果参数继承自接口,则将字段值添加到控制器参数的中间件

C# - middleware that adds field value to controller argument if argument inherits from interface

我可以使用一些建议或指示。我的中间件知识今天让我失望了。

假设我有一个如下所示的控制器端点

public int Create([FromBody] InputDto InputDto)

InputDto 看起来像这样

public class InputDto : IHasSpecialThingy
{
    public SpecialThingy SpecialThingy { get; set; }
    // Plus some other cool fields
}

我想要实现的是一些中间件,它检查对象何时从 "IHasSpecialThingy" 继承,将 SpecialThingy 添加到它上面。

我尝试创建自己的 IModelBinder,但收效甚微。

不幸的是,中间件不是我的强项。任何建议将不胜感激。

提前感谢您的帮助。

编辑

我从带有自定义实现的 IActionFilter 开始。应该不错。仍然需要为它找出一些依赖注入。我会 post 当我清理了很多之后回复。仍然会保持它打开一段时间,因为有人可能会有更好的解决方案。

我找到了解决问题的方法。请看下面的代码。

public class SpecialThingyFilter : IActionFilter
{
    public bool AllowMultiple { get; }

    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
    {
        var commandsWithSpecialThingy = actionContext.ActionArguments
            .Where(x => x.Value != null && x.Value.GetType().GetInterfaces().Contains(typeof(IHasSpecialThingy)))
            .Select(x => x.Value).ToList();

        if (!commandsWithSpecialThingy.Any())
        {
            return await continuation.Invoke();
        }

        foreach (var dto in commandsWithSpecialThingy)
        {
            //Do your magic stuffs here
            ((IHasSpecialThingy)dto).specialThingy = // Something special
        }

        return await continuation.Invoke();
    }
}

如果您的 DI 容器设置正确,您也可以在操作过滤器中使用 DI。

var specialtyService = actionContext.ControllerContext
      .Configuration.DependencyResolver
      .GetService(typeof(ISpecialtyService)) as ISpecialtyService;

如果您有任何问题,或者遇到他的问题并需要帮助解决类似问题,请告诉我。