我有一个非常广泛的Web API应用程序,几个不同的系统用它来收集数据。我被要求在每个方法的结果中添加一个属性,用于执行该方法所花费的时间。我可以在动作过滤器中使用OnActionExecuting / OnActionExecuted来做到这一点,但是我需要找出最好的方法来返回时间而不会破坏我已经拥有的东西。
对于更复杂的对象,我可以从包含TimeTaken属性的基类扩展该类:
public class ApiBaseModel {
public int TimeTaken {get;set;}
}
public class ApiModel : ApiBaseModel {
// other properties
}
// in Web API controller
[ApiTimeTakenFilter]
[HttpGet]
public ApiModel GetApiModel() {
return new ApiModel();
}
// in filter
public override void OnActionExecuting(HttpActionContext actionContext)
{
base.OnActionExecuting(actionContext);
actionContext.Request.Properties[StopwatchKey] = Stopwatch.StartNew();
}
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
Stopwatch stopwatch = (Stopwatch)actionExecutedContext.Request.Properties[StopwatchKey];
long delay = stopwatch.ElapsedMilliseconds;
var objectContent = actionExecutedContext.Response.Content as ObjectContent;
if (objectContent != null)
{
var value = objectContent.Value; //holding the returned value
if (value is ApiBaseModel)
{
// put the delay into the object
((ApiBaseModel)value).TimeTaken = delay;
}
}
}
在不破坏以前版本的API方面应该没问题,但我有很多返回简单对象的方法,例如
[ApiTimeTakenFilter]
[HttpGet]
public bool IsOK {
return true;
}
因此,如果我将其更改为复杂的返回类型,我将破坏现有用户的API的完整性。
我是否可以使用其他机制为所有方法传递TimeTaken值,而不会破坏API?
感谢。
答案 0 :(得分:4)
您可以将其添加到Http Response标头中。然后你不会破坏任何现有的代码,感兴趣的客户可以检索它。
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
base.OnActionExecuted(actionExecutedContext);
Stopwatch stopwatch = (Stopwatch)actionExecutedContext.Request.Properties[StopwatchKey];
long delay = stopwatch.ElapsedMilliseconds;
actionExecutedContext.Response.Headers.Add("requestTime", delay.ToString());
}
您还可以在WebApiConfig.cs文件中全局注册过滤器。