【问题标题】:Creating a route that can accept a DateTime in the URI with asp.net web api 2 attribute routing使用 asp.net web api 2 属性路由创建可以在 URI 中接受 DateTime 的路由
【发布时间】:2013-11-10 15:09:23
【问题描述】:

我正在尝试查看是否需要编写自定义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”作为“槽”值。

按照此处的指南: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/01PUT /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,但无济于事。

我很确定我可以让它与自定义 IHttpRouteConstraint 一起工作,我只是不想做一些可能内置的事情。

谢谢!

【问题讨论】:

    标签: asp.net-web-api asp.net-web-api-routing


    【解决方案1】:

    一个选项是将 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
    

    【讨论】:

    • startDate.ToString("s", CultureInfo.InvariantCulture);代码中的s是什么?
    • 仅供参考,“s”指定将日期格式化为可排序模式,请参阅:Microsoft Docs
    【解决方案2】:

    Web API 日期时间约束在解析日期时间方面没有做任何特别的事情,如下所示(源代码here)。 如果您的请求 url 类似于 var/1/slot/2012-01-01 1:45:30 PMvar/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;
    }
    

    【讨论】:

    • 谢谢!为此,我最终创建了自己的约束。事实证明它非常容易。
    • 看起来由于 codeplex 关闭,源代码链接即将失效。看来这已经在 Github 上被克隆了here
    猜你喜欢
    • 2017-03-24
    • 2013-07-10
    • 1970-01-01
    • 1970-01-01
    • 2017-03-17
    • 2017-08-16
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多