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

Ale*_*der 1 c# asp.net-web-api

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

/api/SomeControllerFunction?loglevel=(someint)
Run Code Online (Sandbox Code Playgroud)

从控制器内部的函数中,我可以初始化一个 LogCollector:

[HttpGet] 
SomeControllerFunction(int loglevel = 0)
{
    LogCollector logger = new LogCollector(loglevel)
}
Run Code Online (Sandbox Code Playgroud)

为了不经常重复自己,我想通过将它添加到 BaseController 的构造函数中来将其隐藏在类层次结构中,我的所有控制器都将从该构造函数继承:

public class BaseController: ApiController
{
    internal LogCollector Logger
    BaseController()
    {
        Logger = new LogCollector(loglevel);
    }
Run Code Online (Sandbox Code Playgroud)

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

Igo*_*gor 5

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

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

家庭控制器.cs

[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}
Run Code Online (Sandbox Code Playgroud)