简体   繁体   中英

pass value returned from a method to action filter

I have _serviceOne injected into my controller that has a method which returns an int value. I'm trying to pass this value into my custom action filter.

This isn't working and I am getting the error: An object reference is required for the non-static field, method, or property 'NameController._serviceOne' where I try to set the Number = _serviceOne.GetIntNumber .

I am aware that I can access a value if it is inside the controller (eg: controller parameter, ViewBag, ViewData, a variable in the controller), but I want to pass the value to the CustomActionFilter filter's Number property.

The filter and service method work the way I want it to, but it won't let me pass the value from _serviceOne.GetIntNumber into the filter. Why is this not working, and how could I make it work?

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);
    }
}

Attributes are created at compile time so it's not possible to pass them run-time values in the constructor.

Instead, you can access NameController 's instance of the service, like this:

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
    }
}

See also Access a controller's property from an action filter

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM