繁体   English   中英

asp.net core api 模型中的 datetimeoffset

[英]datetimeoffset in the asp.net core api model

我有一个这样的模型

class MyModel{
    public DateTimeOffset plannedStartDate {get;set;}
}

和这样的动作

[HttpPost]
public IActionResult Get(MyModel activityUpdate){
}

我从 angular 发送请求作为 json

{
   plannedStartDate: 2019-03-04T16:00:00.000Z
}

这是一个有效的日期

在此处输入图片说明

但我在 api 中得到的是错误的

在此处输入图片说明

如果我在直接窗口中检查变量,我可以看到偏移量无法正确解析在此处输入图片说明

我试图将 mvc 选项更改为

service.AddMvc()
.AddJsonOptions(opt=>
    opt.SerializerSettings.DateParseHandling=DateParseHandling.DateTimeOffset);

这没有帮助,我认为这与反序列化选项无关。 我还有其他选项可以编写自定义 modelBinder 吗?

如果您的客户端使用application/json发送请求,则控制器应指定[FromBody]以启用JsonInputFormatter来绑定模型。

public IActionResult Get([FromBody]MyModel activityUpdate)
{
    //your code.
}

要启用绑定DateTimeOffset ,您可以实现自己的JsonInputFormatter例如

public class DateTimeOffSetJsonInputFormatter : JsonInputFormatter
{
    private readonly JsonSerializerSettings _serializerSettings;
    public DateTimeOffSetJsonInputFormatter(ILogger logger
        , JsonSerializerSettings serializerSettings
        , ArrayPool<char> charPool
        , ObjectPoolProvider objectPoolProvider
        , MvcOptions options
        , MvcJsonOptions jsonOptions) 
            : base(logger, serializerSettings, charPool, objectPoolProvider, options, jsonOptions)
    {
        _serializerSettings = serializerSettings;
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding encoding)
    {
        var request = context.HttpContext.Request;
        using (var reader = new StreamReader(request.Body))
        {
            var content = await reader.ReadToEndAsync();
            var resource = JObject.Parse(content);
            var result = JsonConvert.DeserializeObject(resource.ToString(), context.ModelType);
            foreach (var property in result.GetType().GetProperties())
            {
                if (property.PropertyType == typeof(DateTimeOffset))
                {
                    property.SetValue(result, DateTimeOffset.Parse(resource[property.Name].ToString()));
                }
            }
            return await InputFormatterResult.SuccessAsync(result);
        }
    }
}

Startup.cs注册它,例如

services.AddMvc(mvcOptions => {
    var serviceProvider = services.BuildServiceProvider();
    var jsonInputLogger = serviceProvider.GetRequiredService<ILoggerFactory>().CreateLogger<DateTimeOffSetJsonInputFormatter>();
    var jsonOptions = serviceProvider.GetRequiredService<IOptions<MvcJsonOptions>>().Value;
    var charPool = serviceProvider.GetRequiredService<ArrayPool<char>>();
    var objectPoolProvider = serviceProvider.GetRequiredService<ObjectPoolProvider>();

    var customJsonInputFormatter = new DateTimeOffSetJsonInputFormatter(
                jsonInputLogger,
                jsonOptions.SerializerSettings,
                charPool,
                objectPoolProvider,
                mvcOptions,
                jsonOptions
        );
    mvcOptions.InputFormatters.Insert(0, customJsonInputFormatter);
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

使用 ISO 8601 格式字符串: "yyyy-MM-ddTHH:mm:ssZZZ"

这应该将您的日期正确绑定到 DateTimeOffset,并且应该包括偏移值。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM