NewtonSoft Json DeserializeObject 空 Guid 字段
Posted
技术标签:
【中文标题】NewtonSoft Json DeserializeObject 空 Guid 字段【英文标题】:NewtonSoft Json DeserializeObject empty Guid field 【发布时间】:2014-03-21 10:09:04 【问题描述】:我正在使用带有 html CSS jQuery KnockoutJs 前端的 ASP.NET MVC C#。
我的 HTML 页面上有一个模式联系表。这个想法是,如果我创建一个新联系人,模态表单会弹出一个空白值,包括一个空白的隐藏 id 字段。
如果我编辑联系人,则会弹出模式表单,其中包含已填写的字段,包括隐藏的 id 字段。
在我的控制器中,我打算这样做:
public JsonResult Contact(string values)
var contact = JsonConvert.DeserializeObject<contact>(values);
if (contact.Id.Equals(Guid.Empty))
// create a new contact in the database
else
// update an existing one
但是,我收到一条错误消息,提示 can't convert "" to type Guid
你如何使用 NewtonSoft Json 解决这个问题,我在 Custom JsonConverter 上查看了here,它似乎是正确的,但我不知道该去哪里有了这个。
【问题讨论】:
您是否尝试过将contact.Id
属性设为可空?这可能会解决它。
我使用数据库中使用的Contact
模型,因此将其设为可空会很糟糕。
【参考方案1】:
自定义转换器看起来像这样,但我觉得对于如此微不足道的事情来说它有点矫枉过正。
/// <summary>
/// Converts a <see cref="Guid"/> to and from its <see cref="System.String"/> representation.
/// </summary>
public class GuidConverter : JsonConverter
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>Returns <c>true</c> if this instance can convert the specified object type; otherwise <c>false</c>.</returns>
public override bool CanConvert(Type objectType)
return objectType.IsAssignableFrom(typeof(Guid));
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
try
return serializer.Deserialize<Guid>(reader);
catch
return Guid.Empty;
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
serializer.Serialize(writer, value);
用法:
class Contact
[JsonConverter(typeof(GuidConverter))]
public Guid Id get; set;
或者:
var contact = JsonConvert.DeserializeObject<contact>(values, new GuidConverter());
编辑
我认为你的 JSON 看起来很像这样:
"id": "",
"etc": "..."
如果您可以这样做,问题可能会得到解决:
"id": null,
"etc": "..."
【讨论】:
现在测试一下 基本上,它所做的只是将默认转换器包装在try-catch
块中。如果转换失败,则默认为Guid.Empty
。不是最有效的解决方案。例如,您可以首先使用String.IsNullOrEmpty()
来避免异常。
最好的解决方案是在 JSON 数据中完全不包含 Id
属性。你能做到吗?
你会把它放在哪里,你是说遍历传递回操作的字符串并找到 id 并将 guid.empty 放入其中吗?
我不能,因为我试图在整个应用程序中实现单一的模态标准,所以前端只需要更新一个地方,后端也一样【参考方案2】:
我遇到了 Guid.Empty (00000000-0000-0000-0000-000000000000) 值被反序列化为 Null 指南导致错误的问题。当我将 JsonSerializerSettings.DefaultValueHandling 值设置为 DefaultValueHandling.IgnoreAndPopulate 时,反序列化 Guid 属性被设置为默认值
var serializedObject = JsonConvert.DeserializeObject<T>(serializedString, new JsonSerializerSettings DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate );
【讨论】:
这个答案只是帮助我完成了 2 小时的调试会话。谢谢!【参考方案3】:GUID 和 JSON 字符串的完整示例
string content = "\"data\":\"Type\":\"Foo\",\"Description\":\"bar \",\"Software\":\"baz\",\"Version\":\"qux\",\"Url\":\"http://example.com\",\"DatabasePortNumber\":1,\"Id\":\"2cdc66f1-0000-0000-39ac-233c00000000\"";
var result_SystemText = System.Text.Json.JsonSerializer.Deserialize<SystemApplicationResponse>(content); //Will result in null-object
var result_Newtonsoft = Newtonsoft.Json.JsonConvert.DeserializeObject<SystemApplicationResponse>(content); //Will result in correctly serialized object
public class SystemApplicationResponse
public SystemApplicationDto Data get; set;
public class SystemApplicationDto
public SystemApplicationDtoType Type get; set;
public string Description get; set;
public string Software get; set;
public string Version get; set;
public string Url get; set;
public int DatabasePortNumber get; set;
public System.Guid Id get; set;
public enum SystemApplicationDtoType
Foo = 0
参考:https://github.com/dotnet/runtime/issues/31465#
【讨论】:
以上是关于NewtonSoft Json DeserializeObject 空 Guid 字段的主要内容,如果未能解决你的问题,请参考以下文章
无法将类型“newtonsoft.json.linq.jtoken”隐式转换为 newt“newtonsoft.json.linq.jvalue”
从 JSON 检索项目时获取“无法将 Newtonsoft.Json.Linq.JObject 转换为 Newtonsoft.Json.Linq.JToken”