Asp.net web api 向Web API输出添加属性的最佳实践

Asp.net web api 向Web API输出添加属性的最佳实践,asp.net-web-api,Asp.net Web Api,我有一个相当广泛的Web API应用程序,几个不同的系统使用它来收集数据。我被要求为每个方法的结果添加一个属性,以计算该方法执行所需的时间。我可以在动作过滤器中使用OnActionExecuting/OnActionExecuted来实现这一点,但我需要找出返回时间的最佳方式,而不破坏我已经拥有的时间 对于更复杂的对象,我可以从包含TimeTake属性的基类扩展该类: public class ApiBaseModel { public int TimeTaken {get;set;}

我有一个相当广泛的Web API应用程序,几个不同的系统使用它来收集数据。我被要求为每个方法的结果添加一个属性,以计算该方法执行所需的时间。我可以在动作过滤器中使用OnActionExecuting/OnActionExecuted来实现这一点,但我需要找出返回时间的最佳方式,而不破坏我已经拥有的时间

对于更复杂的对象,我可以从包含TimeTake属性的基类扩展该类:

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的完整性

是否有其他机制可以用于在不破坏API的情况下为所有方法传递耗时值


谢谢。

您可以像这样将其添加到Http响应头中。然后,您将不会破坏任何现有代码,感兴趣的客户可以检索它

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文件中全局注册筛选器。

您是否考虑过将其从筛选器写入Http响应头?简单且不中断。很好。非常感谢,这正是我想要的!是的,过滤器是全局注册的,我只是想在示例代码中演示它的应用。