如何在动作过滤器中获取当前模型

ade*_*lin 14 c# asp.net-core-mvc asp.net-core

我有一个通用的动作过滤器,我想在OnActionExecuting方法中获得当前的模型.我目前的实现如下:

public class CommandFilter<T> : IActionFilter where T : class, new()
{
    public void OnActionExecuting(ActionExecutingContext actionContext)
    {
        var model= (T)actionContext.ActionArguments["model"];
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我的所有型号名称相同,它的效果很好.但我想使用不同的模型名称.

如何解决这个问题呢?

编辑

public class HomeController : Controller
{
    [ServiceFilter(typeof(CommandActionFilter<CreateInput>))]
    public IActionResult Create([FromBody]CreateInput model)
    {
        return new OkResult();
    }
}
Run Code Online (Sandbox Code Playgroud)

Set*_*Set 9

ActionExecutingContext.ActionArguments只是一个字典,

    /// <summary>
    /// Gets the arguments to pass when invoking the action. Keys are parameter names.
    /// </summary>
    public virtual IDictionary<string, object> ActionArguments { get; }
Run Code Online (Sandbox Code Playgroud)

如果您需要避免使用硬编码的参数名称("模型"),则需要循环使用它.来自asp.net 的相同SO答案:

当我们创建一个通用的动作过滤器,需要为一些特定的需求处理一类类似的对象时,我们可以让我们的模型实现一个接口=>知道哪个参数是我们需要处理的模型,我们可以调用这些方法界面.

在你的情况下,你可能写这样的东西:

public void OnActionExecuting(ActionExecutingContext actionContext)
{
    foreach(var argument in actionContext.ActionArguments.Values.Where(v => v is T))
    {
         T model = argument as T;
         // your logic
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我使用了 `context.ActionArguments.Values.OfType&lt;MyType&gt;().Single()` 因为我知道我想要的特定类型 (2认同)

Set*_*Set 7

你可以使用ActionExecutingContext.Controller财产

    /// <summary>
    /// Gets the controller instance containing the action.
    /// </summary>
    public virtual object Controller { get; }
Run Code Online (Sandbox Code Playgroud)

并将结果转换为基础MVC Controller可以访问模型:

((Controller)actionExecutingContext.Controller).ViewData.Model
Run Code Online (Sandbox Code Playgroud)