4

我正在尝试查看是否需要编写自定义内容IHttpRouteConstraint,或者是否可以与内置的内容搏斗以获得我想要的东西。我在任何地方都找不到任何好的文档。

基本上,这是我的行动:

[Route("var/{varId:int:min(1)}/slot/{*slot:datetime}")]
public async Task<HttpResponseMessage> Put(int varId, DateTime slot)
{
    ...
}

我想要的是能够这样称呼它: PUT /api/data/var/1/slot/2012/01/01/131516并让框架将 19 绑定到 var id 和DateTime值为“2012 年 1 月 1 日,下午 1:15:16”作为“插槽”值的 a。

按照这里的指南:http ://www.asp.net/web-api/overview/web-api-routing-and-actions/create-a-rest-api-with-attribute-routing我能够得到它通过仅传递日期段来工作,即PUT /api/data/var/1/slot/2012/01/01or PUT /api/data/var/1/slot/2012-01-01,但这只会给我一个数据值,没有时间分量。

有些事情告诉我,试图以任何理智的方式通过 URI 段传递时间是一个坏主意,但我不确定为什么这是一个坏主意,除了关于本地与 UTC 时间的模糊性。

我还尝试datetime使用正则表达式约束约束,例如{slot:datetime:regex(\\d{4}/\\d{2}/\\d{2})/\\d{4})}尝试让它解析2013/01/01/151617为 DateTime 之类的东西,但无济于事。

我很确定我可以让它与 custom 一起使用IHttpRouteConstraint,我只是不想做一些可能内置的东西。

谢谢!

4

2 回答 2

8

一个选项是将 DateTime 作为查询字符串参数传递(请参阅 [FromUri]

例如

[Route("api/Customer/{customerId}/Calls/")]
public List<CallDto> GetCalls(int customerId, [FromUri]DateTime start, [FromUri]DateTime end)

这将有一个签名

GET api/Customer/{customerId}/Calls?start={start}&end={end}

创建查询字符串日期

startDate.ToString("s", CultureInfo.InvariantCulture);

查询字符串看起来像

api/Customer/81/Calls?start=2014-07-25T00:00:00&end=2014-07-26T00:00:00
于 2014-07-25T12:48:42.697 回答
4

Web API 日期时间约束在解析日期时间方面没有做任何特别的事情,您可以在下面注意到(这里的源代码)。如果您的请求 url 类似于var/1/slot/2012-01-01 1:45:30 PMor var/1/slot/2012/01/01 1:45:30 PM,它似乎可以正常工作......但我想如果您需要充分的灵活性,那么创建自定义约束是最好的选择......

public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, IDictionary<string, object> values, HttpRouteDirection routeDirection)
{
    if (parameterName == null)
    {
        throw Error.ArgumentNull("parameterName");
    }

    if (values == null)
    {
        throw Error.ArgumentNull("values");
    }

    object value;
    if (values.TryGetValue(parameterName, out value) && value != null)
    {
        if (value is DateTime)
        {
            return true;
        }

        DateTime result;
        string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
        return DateTime.TryParse(valueString, CultureInfo.InvariantCulture, DateTimeStyles.None, out result);
    }
    return false;
}
于 2013-10-30T20:59:58.027 回答