gpt4 book ai didi

c# - 当单个对象属性是字符串时,如何防止将其转换为 DateTime

转载 作者:行者123 更新时间:2023-11-30 23:18:48 30 4
gpt4 key购买 nike

这是我必须使用的模型的简化版本:

class InputModel
{
public string Name { get; set; }
public object Value { get; set; }
}

以及controller的相关部分:

class Controller : ApiController
{
[HttpPut]
public async Task<IHttpActionResult> Update([FromBody]InputModel model)
{
//implementation
}
}

InputModel 类的 Value 属性可以是任何类型,它是哪种类型只有在模型被发送到的一段遗留代码中才能知道,我无法控制。

我在请求正文中出现以下 json 时出现的问题:

{
"name": "X",
"value": "2001-10-17T13:55:11.123"
}

默认行为是解析此 json,以便将 Value 属性转换为 DateTime。然而,DateTimes 的处理方式与遗留代码中的字符串非常不同,处理后数据会丢失(例如:在持久保存到数据库时,毫秒部分会被删除)。因此,当稍后请求相同的值时,返回值为“2001-10-17T13:55:11”(缺少毫秒数)。

当然,我可以通过在我的 web api 配置中进行全局设置来解决这个问题:

httpConfiguration.Formatters.JsonFormatter.SerializationSettings.DateParseHandling = DateParseHandling.None;

但是这样做也会禁用对其他方法中的模型和 Controller 的模型解析 DateTimes,这些模型具有需要默认行为的模型。

我正在寻找的是类似于以下(虚构的)代码的内容:

class InputModel
{
public string Name { get; set; }

[JsonSerializerSettings(DateParseHandling = DateParseHandling.None)]
public object Value { get; set; }
}

但我不知道如何实现这一点。任何帮助将不胜感激。

最佳答案

我们可以做的是添加一个 custom JsonConverterInputModel 类型临时切换 JsonReader.DateParseHandling:

[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)]
class InputModel
{
public string Name { get; set; }
public object Value { get; set; }
}

public class DateParseHandlingConverter : JsonConverter
{
readonly DateParseHandling dateParseHandling;

public DateParseHandlingConverter(DateParseHandling dateParseHandling)
{
this.dateParseHandling = dateParseHandling;
}

public override bool CanConvert(Type objectType)
{
throw new NotImplementedException();
}

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var old = reader.DateParseHandling;
try
{
reader.DateParseHandling = dateParseHandling;
existingValue = existingValue ?? serializer.ContractResolver.ResolveContract(objectType).DefaultCreator();
serializer.Populate(reader, existingValue);
return existingValue;
}
finally
{
reader.DateParseHandling = old;
}
}

public override bool CanWrite { get { return false; } }

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}

请注意,如果要反序列化的 JSON 包含嵌套数组或对象,则所有递归包含的值都将使用 DateParseHandling.None 进行解析。

有人可能会问,为什么不直接向属性添加转换器,就像这样?

class InputModel
{
public string Name { get; set; }
[JsonConverter(typeof(DateParseHandlingConverter), DateParseHandling.None)]
public object Value { get; set; }
}

事实证明这是行不通的,因为当时 JsonConverter.ReadJson()被调用时,读取器已经前进到日期字符串并将其标记为DateTime因此必须将转换器应用于包含类型。

关于c# - 当单个对象属性是字符串时,如何防止将其转换为 DateTime,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40632820/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com