所以我有一个用 C# 编写的 WebAPI 2 Controller ,它采用 DateTime 类型的查询参数等。这是一个基于日期过滤器从数据存储中返回所有值的 API。 比如,让我们说:
public MyThing GetThing([FromUri]DateTime startTime)
{
// filter and return some results
}
我遇到了两个问题:
- 出于某种原因,尽管传入了 ISO 8601 UTC 格式(带 Z)日期,WebAPI 仍将其反序列化为本地 DateTime,而不是 Utc。这显然是不可取的。我不确定如何修改管道以使其正确理解 UTC-0 日期时间。
- 我将返回资源的链接作为响应主体的一部分,其中我使用 UrlHelper 对象(从父 ApiController 抽象类获得)Link() 方法生成 href。我正在传递要添加到路由的查询参数集合。无论出于何种原因,以非 ISO8601 格式传递 DateTime 格式。我找不到这是在哪里控制的。我不想明确地使用 ToString() 它,因为它不是普遍强制执行的。
简而言之,我想弄清楚如何确保
- 通过 FromUri 查询参数传入的 DateTimes 被正确理解为 ISO8601,包括适当的时区偏移
- UrlHelper.Link() 以普遍可执行的静态类型方式在输出 URI 字符串中生成符合 ISO8601 标准的日期时间。
WebAPI 2 确实为格式化 JSON 提供了很好的 Hook ,我确实使用了它,因此只需返回 JSON 正文中的 DateTime 使用 ISO8601 格式根据需要格式化它,并且它在 [FromBody] 中被正确理解JSON 正文。虽然我找不到围绕 URI 处理拉动字符串的方法,但我真的很想这样做!
最佳答案
您可以使用模型绑定(bind)器将传入数据转换为您的模型。
GetThings([ModelBinder(typeof(UtcDateTimeModelBinder)), FromUri] DateTime dt){//do somthing}
public class UtcDateTimeModelBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (bindingContext == null)
{
throw new ArgumentNullException(nameof(bindingContext));
}
if (bindingContext.ModelMetadata.ModelType == typeof(DateTime))
{
var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
var str = valueProviderResult.AttemptedValue;
return DateTime.Parse(str).ToUniversalTime();
}
return null;
}
通过这种方式,您可以将其设置为 DateTime 的默认模型。
ModelBinders.Binders.Add(typeof(DateTime), new UtcDateTimeModelBinder());
关于c# - 在 WebAPI 2 中控制 DateTime 参数格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39628074/