i have a model like this
class MyModel{
public DateTimeOffset plannedStartDate {get;set;}
}
and an action like this
[HttpPost]
public IActionResult Get(MyModel activityUpdate){
}
and i'm sending request from angular as a json
{
plannedStartDate: 2019-03-04T16:00:00.000Z
}
which is a valid date
but what i'm getting in the api is wrong
if i inspet the variable in the immediate windows i can see that the offset couldnt' parse correctly
i tried to change the mvc options to
service.AddMvc()
.AddJsonOptions(opt=>
opt.SerializerSettings.DateParseHandling=DateParseHandling.DateTimeOffset);
which didn't help, i dont' think it's about deserialize options. do i have any other optiosn that writing custom modelBinder?
If your client send request with application/json
, the controller should specify [FromBody]
to enable JsonInputFormatter
to bind the model.
public IActionResult Get([FromBody]MyModel activityUpdate)
{
//your code.
}
For enable binding DateTimeOffset
, you could implement your own JsonInputFormatter
like
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);
}
}
}
Register it in Startup.cs
like
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);
Use the ISO 8601 format string: "yyyy-MM-ddTHH:mm:ssZZZ"
This should bind your date properly to DateTimeOffset, and should include the offset value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.