C# WebAPI:从控制器构造函数检索GET参数

C# WebAPI:从控制器构造函数检索GET参数,c#,asp.net-web-api,C#,Asp.net Web Api,对我的WebAPI的每次调用都可能(也可能不)包含GET参数 /api/SomeControllerFunction?loglevel=(someint) 通过控制器内的函数,我可以初始化LogCollector: [HttpGet] SomeControllerFunction(int loglevel = 0) { LogCollector logger = new LogCollector(loglevel) } 为了不经常重复,我想通过将其添加到BaseController

对我的WebAPI的每次调用都可能(也可能不)包含GET参数

/api/SomeControllerFunction?loglevel=(someint)
通过控制器内的函数,我可以初始化LogCollector:

[HttpGet] 
SomeControllerFunction(int loglevel = 0)
{
    LogCollector logger = new LogCollector(loglevel)
}
为了不经常重复,我想通过将其添加到BaseController的构造函数中,将其隐藏在类层次结构中,我的所有控制器都将从该构造函数继承:

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

但是如何从构造函数访问GET参数呢?

构造函数调用得太早,您无法从那里访问参数。但是,您可以覆盖
Initialize
方法,并从上下文检索GET参数:

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

构造函数调用得太早,您无法从那里访问参数。但是,您可以覆盖
Initialize
方法,并从上下文检索GET参数:

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

您可以直接将
LogCollector
注入方法,而不是使用构造函数。如果您确实想使用构造函数,那么应该使用Di/IoC框架,因为这样更合适

在下面的示例中,您可以使用一个自定义的
ActionFilterAttribute
实例,该实例基于传入(可选)日志级别注入记录器。然后使用操作上的
RouteAttribute
在路由中定义日志级别。
RouteAttribute
还定义了日志级别的默认值,因此在调用该操作时不需要该值

loginjectorfilteratAttribute.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);
    }
}
[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}
HomeController.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);
    }
}
[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}

您可以直接将
LogCollector
注入方法,而不是使用构造函数。如果您确实想使用构造函数,那么应该使用Di/IoC框架,因为这样更合适

在下面的示例中,您可以使用一个自定义的
ActionFilterAttribute
实例,该实例基于传入(可选)日志级别注入记录器。然后使用操作上的
RouteAttribute
在路由中定义日志级别。
RouteAttribute
还定义了日志级别的默认值,因此在调用该操作时不需要该值

loginjectorfilteratAttribute.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);
    }
}
[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}
HomeController.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);
    }
}
[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}