datetimeoffset в модели API ядра asp.net - PullRequest
0 голосов
/ 06 марта 2019

У меня есть такая модель

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

и подобное действие

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

, и я отправляю запрос от angular как json

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

, которая является действительной датой

enter image description here

но то, что я получаю в API, неверно

enter image description here

Если я ввел переменную в ближайшие окна, я вижу, что смещение не может правильно проанализировать enter image description here

Я попытался изменить MVCварианты

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

, которые не помогли, я не думаю, что речь идет о десериализации параметров.у меня есть какие-либо другие optiosn, которые пишут пользовательские modelBinder?

1 Ответ

1 голос
/ 06 марта 2019

Если ваш клиент отправляет запрос с 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...