对我的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参数?
答案 0 :(得分:4)
构造函数过早调用,您无法从那里访问参数。但是,您可以覆盖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);
}
答案 1 :(得分:4)
您可以将LogCollector
直接注入方法,而不是使用构造函数。如果你确实想使用构造函数,你应该使用Di / IoC框架,因为这更合适。
在下面的示例中,您可以使用自定义ActionFilterAttribute
实例,该实例根据传入(可选)日志级别注入Logger。然后,在操作中使用RouteAttribute
在路径中定义日志级别。 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);
}
}
<强> HomeController.cs 强>
[HttpGet]
[Route("api/Home/Get/{loglevel:int=1}")]
[LogInjectorFilter]
public IHttpActionResult Get(LogCollector logger)
{
}