【发布时间】:2016-09-21 23:37:27
【问题描述】:
所以我有一个用 C# 编写的 WebAPI 2 控制器,其中包含一个 DateTime 类型的查询参数。这是一个基于日期过滤器从数据存储中返回所有值的 API。 比如说:
public MyThing GetThing([FromUri]DateTime startTime)
{
// filter and return some results
}
我遇到了两个问题:
- 出于某种原因,尽管传入了 ISO 8601 UTC 格式(带有 Z)日期,但 WebAPI 将其反序列化为本地 DateTime,而不是 Utc。这显然是不可取的。我不确定如何修改管道以使其正确理解 UTC-0 DateTimes。
- 我将一个链接返回到作为响应正文的一部分的资源,其中我使用 UrlHelper 对象(从父 ApiController 抽象类获得)Link() 方法来生成一个 href。我正在传递一组我想添加到路由中的查询参数。无论出于何种原因,传递 DateTime 都会将其格式化为非 ISO8601 格式。我找不到这是在哪里控制的。我不想明确 ToString() 它,因为这不能普遍执行。
简而言之,我想弄清楚如何确保这一点
- 通过 FromUri 查询参数传入的日期时间被正确理解为 ISO8601,包括适当的时区偏移
- UrlHelper.Link() 以通用的静态类型方式在输出 URI 字符串中生成符合 ISO8601 的日期时间。
WebAPI 2 确实提供了用于格式化 JSON 的精彩钩子,我确实使用了它,因此只需返回 JSON 正文中的 DateTime 即可使用 ISO8601 格式根据需要对其进行格式化,并且在 [FromBody] 中也可以正确理解JSON 正文。虽然我找不到围绕 URI 处理拉字符串的方法,但我真的很想这样做!
【问题讨论】:
-
关于 UrlHelper,它似乎有点过时了,不确定。我相信它以(内部)Bind 方法结束:sourcebrowser.io/Browse/ASP-NET-MVC/aspnetwebstack/src/… 如您所见,它只是在参数上执行
Convert.ToString(value, CultureInfo.InvariantCulture)。因此,唯一的解决方案是添加一个覆盖 ToString() 的 DateTime 包装类以发送回您想要的内容。 -
对于FromUri,我建议你使用[ValueProvider(typeof(MyUriValueProviderFactory))]而不是[FromUri]并实现MyUriValueProviderFactory。它必须派生自 ValueProviderFactory。
-
约会总是一个巨大的痛苦。 10 次中有 9 次更容易将其作为字符串传递,然后在您自己的代码中使用您需要的任何转换。
-
你在使用路由属性吗?过去我遇到了日期问题,但例如对于方法
public async Task<IHttpActionResult> GetDetails(DateTime? start = null, DateTime? end = null),我正在使用这条路线[Route("details/{start:datetime:regex(\\d{4}-\\d{2}-\\d{2})?}/{end:datetime:regex(\\d{4}-\\d{2}-\\d{2})?}")]
标签: c# datetime asp.net-web-api format