1

Every call to my WebAPI may (or may not) contain the GET parameter

/api/SomeControllerFunction?loglevel=(someint)

From the function inside the controller I can initialize a LogCollector:

[HttpGet] 
SomeControllerFunction(int loglevel = 0)
{
    LogCollector logger = new LogCollector(loglevel)
}

To not repeat myself too often, I want to hide this in the class hierarchy by adding it into the constructor of a BaseController, from which all my controllers shall inherit:

public class BaseController: ApiController
{
    internal LogCollector Logger
    BaseController()
    {
        Logger = new LogCollector(loglevel);
    }

But how can I access a GET parameter from the constructor?

2 Answers 2

5

Instead of using the constructor you could inject the LogCollector directly into the method. If you did want to use the constructor you should use a Di / IoC framework as that would be more appropriate.

In the example below you can use a custom ActionFilterAttribute instance which injects the Logger based the incoming (optional) log level. The log level is then defined in the route using a RouteAttribute on the action. The RouteAttribute also defines a default value for the log level so it is not required when calling that action.

LogInjectorFilterAttribute.cs

public class LogInjectorFilterAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        const string key = "loglevel";
        if(actionContext.ControllerContext.RouteData.Values.ContainsKey(key))
        {
            var loglevel = int.Parse(actionContext.ControllerContext.RouteData.Values[key].ToString());
            LogCollector logger = new LogCollector(loglevel);
            actionContext.ActionArguments["logger"] = logger;
        }
        base.OnActionExecuting(actionContext);
    }
}

HomeController.cs

[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}
Sign up to request clarification or add additional context in comments.

Comments

4

The constructor is invoked too early, you can't access the parameters from there. However, you can override the Initialize method and retrieve the GET parameters from the context:

protected override void Initialize(HttpControllerContext controllerContext)
{
    foreach (var parameter in controllerContext.Request.GetQueryNameValuePairs())
    {
        Debug.WriteLine(string.Format("{0} = {1}", parameter.Key, parameter.Value));
    }

    base.Initialize(controllerContext);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.