【发布时间】:2015-09-28 07:45:24
【问题描述】:
我有一个 C# MVC 应用程序,它将数据作为 JSON 字符串存储在 XML 文档和 MySQL DB 表中。
最近我收到了在MySQL数据库字段中存储JSON字符串的需求,通过Newtonsoft.Json转换成C#对象,所以我决定实现一个TypeConverter将 JSON 字符串转换为自定义 C# 模型。
不幸的是,当 TypeConverter 属性添加到我的 C# 模型时,我无法在解决方案中的任何地方使用以下命令来反序列化我的 JSON 字符串:
JsonConvert.DeserializeObject<Foo>(json);
删除该属性可解决问题,但这会阻止我将 MySQL DB 字段转换为自定义 C# 对象。
这是我添加了 TypeConverter 属性的 C# 模型:
using System.ComponentModel;
[TypeConverter(typeof(FooConverter))]
public class Foo
{
public bool a { get; set; }
public bool b { get; set; }
public bool c { get; set; }
public Foo(){}
}
这是我的 TypeConverter 类:
using Newtonsoft.Json;
using System;
using System.ComponentModel;
public class FooConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is string)
{
string s = value.ToString().Replace("\\","");
Foo f = JsonConvert.DeserializeObject<Foo>(s);
return f;
}
return base.ConvertFrom(context, culture, value);
}
}
}
将属性添加到 Foo 类后,我立即收到以下错误:
无法将当前 JSON 对象(例如 {"name":"value"})反序列化为“Models.Foo”类型,因为该类型需要 JSON 字符串值才能正确反序列化。
要修复此错误,要么将 JSON 更改为 JSON 字符串值,要么将反序列化类型更改为正常的 .NET 类型(例如,不是像整数这样的原始类型,而不是像数组这样的集合类型或List) 可以从 JSON 对象反序列化。 JsonObjectAttribute 也可以添加到类型中,以强制它从 JSON 对象反序列化。
我正在使用以下字符串(无需添加 TypeConverter 属性即可完美运行):
"{\"Foo\":{\"a\":true,\"b\":false,\"c\":false}}"
不知道这里发生了什么,有什么想法吗?
非常感谢!!!
更新
我发现在接受 Test Class with Foo 作为属性 的 MVC API 控制器 或接受 的控制器上的操作也存在问题当 TypeConverter 属性 被添加到 Foo 类时,Foo 作为一个对象。
这是一个有问题的测试控制器示例:
public class TestController : ApiController
{
[AcceptVerbs("POST", "GET")]
public void PostTestClass(TestClass t)
{
// Returns null when TypeConverter attribute is added to the Foo Class
return t.Foo;
}
AcceptVerbs("POST", "GET")]
public void PostFooObj(Foo f)
{
// Returns null when TypeConverter attribute is added to the Foo Class
return f;
}
}
当上述任一操作通过 AJAX 接收具有以下结构的 JSON 时,TypeConverter 可能会导致覆盖 WebAPI 模型绑定的问题并返回 null:
// eg. PostTestClass(TestClass T)
{'Foo': {'a': false,'b': true,'c': false}};
// eg. PostFooObj(Foo f)
{'a': false,'b': true,'c': false}
将TypeConverter Attribute添加到Foo类时,一旦找到路由,就会调用FooConverter TypeConverter类上的以下方法:
public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
ApiController 的操作未调用 FooConverter TypeController 上的 ConvertFrom 方法,这可能是问题的原因。
这也是类似的情况,没有 TypeConverter 属性,控制器的操作也可以正常工作。
非常感谢任何进一步的帮助!
非常感谢。
【问题讨论】:
-
您的 JSON 字符串是否固定为您所显示的
"{\"Foo\":...}"? -
是的,您是正确的,JSON 在我的测试解决方案中没有改变。我所做的只是添加/删除 TypeConverter 属性。谢谢
-
我很好奇您是否可以使用更类似于
"{\"a\":true,\"b\":false,\"c\":false}"的 JSON 结构,例如没有包装"{\"Foo\":...}"对象。这个 JSON 可以直接使用JsonConvert.DeserializeObject<Foo>(json)反序列化
标签: c# json serialization json.net typeconverter