【问题标题】:pass value returned from a method to action filter将方法返回的值传递给操作过滤器
【发布时间】:2020-01-24 19:47:23
【问题描述】:

我将_serviceOne 注入到我的控制器中,该控制器有一个返回int 值的方法。我正在尝试将此值传递给我的自定义操作过滤器。

这不起作用,我收到错误:An object reference is required for the non-static field, method, or property 'NameController._serviceOne' 我尝试在其中设置 Number = _serviceOne.GetIntNumber

我知道我可以访问控制器内部的值(例如:控制器参数、ViewBag、ViewData、控制器中的变量),但我想将该值传递给CustomActionFilter 过滤器的@987654326 @属性。

过滤器和服务方法按我想要的方式工作,但它不会让我将_serviceOne.GetIntNumber 的值传递到过滤器。为什么这不起作用,我怎样才能使它起作用?

NameController.cs:

public class NameController : Controller
{
    private readonly ServiceOne _serviceOne;

    public NameController(ServiceOne serviceOne)
    {
        _serviceOne = serviceOne;
    }

    [CustomActionFilter(Name = "CorrectName", Number = _serviceOne.GetIntNumber)] //does not work
    [HttpGet]
    public IActionResult Index()
    {
        return View();
    }
}

CustomActionFilter.cs:

public class CustomActionFilter : ActionFilterAttribute
{
    public string Name { get; set; }
    public int Number { get; set; }

    public override void OnActionExecuted(ActionExecutedContext context)
    {
        if (Name == "CorrectName" && Number == 1) {
            RouteValueDictionary routeDictionary = new RouteValueDictionary { { "action", "SomeAction" }, { "controller", "NameController" } };
            context.Result = new RedirectToRouteResult(routeDictionary);
        }

        base.OnActionExecuted(context);
    }
}

【问题讨论】:

    标签: c# asp.net-core model-view-controller service action-filter


    【解决方案1】:

    属性是在编译时创建的,因此无法在构造函数中传递它们的运行时值。

    相反,您可以访问NameController 的服务实例,如下所示:

    public class NameController : Controller
    {
        private readonly ServiceOne _serviceOne;
    
        public ServiceOne ServiceOne => _serviceOne;
    
        public NameController(ServiceOne serviceOne)
        {
            _serviceOne = serviceOne;
        }
    }
    
    public class CustomActionFilter : ActionFilterAttribute
    {
        public string Name { get; set; }
        public int Number { get; set; }
    
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            var controller = context.Controller as NameController;
            var service = controller.ServiceOne;
            //Use the service here
        }
    }
    

    另见Access a controller's property from an action filter

    【讨论】:

    • 酷!可以使用包含 IService 属性的自定义 IControllerService 接口将其扩展为更可测试。从那里您可以访问过滤器中任何已实现的 IService 属性。
    • 感谢您的回答。您能解释一下 public ServiceOne ServiceOne => _serviceOne; 的作用吗?我似乎无法弄清楚 => 部分和双重类名。
    • 这是一个expression-bodied 属性,将_serviceOne 公开。这是必要的,因为您的 ActionFilter 是与 NameController 不同的类,并且无法访问其私有字段。您也可以只公开该字段或将其完全替换为公共属性。
    猜你喜欢
    • 1970-01-01
    • 2010-11-03
    • 2014-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多