What do I need to do so that Json.Net to behaves as if the [Serializable] attribute isn't there?
我有一个问题,其中Web客户端应用程序无法正确反序列化JSON消息。 该错误是由于代表消息的类型被标记为[可序列化]而引起的。
下面是一些代码,重现该问题。 它需要Newtonsoft.Json和Microsoft.AspNet.WebApi.Client NuGet程序包。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | using Newtonsoft.Json; using System; using System.Net.Http; using System.Text; namespace ConsoleApplication7 { internal class Program { private static void Main() { String cargo ="Hello"; SerializableType serializableTypeOriginal = new SerializableType(cargo); String jsonFromSerializableType = JsonConvert.SerializeObject(serializableTypeOriginal); NonSerializableType nonSerializableTypeOriginalNonSerializableType = new NonSerializableType(cargo); String jsonFromNonSerializableType = JsonConvert.SerializeObject(nonSerializableTypeOriginalNonSerializableType); System.Diagnostics.Debug.Assert(jsonFromSerializableType == jsonFromNonSerializableType); HttpContent httpContent = new StringContent(jsonFromSerializableType, new UTF8Encoding(),"application/json"); SerializableType serializableTypeFromSerializableType = httpContent.ReadAsAsync<SerializableType>().Result; //serializableTypeFromSerializableType.A == null ? httpContent = new StringContent(jsonFromSerializableType, new UTF8Encoding(),"application/json"); NonSerializableType nonSerializableTypeFromSerializableType = httpContent.ReadAsAsync<NonSerializableType>().Result; //nonSerializableTypeFromSerializableType.A =="Hello" ? httpContent = new StringContent(jsonFromNonSerializableType, new UTF8Encoding(),"application/json"); SerializableType serializableTypeFromNonSerializableType = httpContent.ReadAsAsync<SerializableType>().Result; //serializableTypeFromNonSerializableType.A == null ? httpContent = new StringContent(jsonFromNonSerializableType, new UTF8Encoding(),"application/json"); NonSerializableType nonSerializableTypeFromNonSerializableType = httpContent.ReadAsAsync<NonSerializableType>().Result; //nonSerializableTypeFromNonSerializableType.A =="Hello" ? } } [Serializable] public class SerializableType { private readonly string _a; public SerializableType(String a) { _a = a; } public string A { get { return _a; } } public override string ToString() { return string.Format("A: {0}", A); } } public class NonSerializableType { private readonly string _a; public NonSerializableType(String a) { _a = a; } public string A { get { return _a; } } public override string ToString() { return string.Format("A: {0}", A); } } } |
这是NuGet软件包文件:
1 2 3 4 5 | <?xml version="1.0" encoding="utf-8"?> <packages> <package id="Microsoft.AspNet.WebApi.Client" version="5.1.1" targetFramework="net45" /> <package id="Newtonsoft.Json" version="4.5.11" targetFramework="net45" /> </packages> |
在我看来,对于未使用[Serializable]属性修饰的类,则JSON.Net将使用构造函数注入在反序列化时对类进行水合。 但是,当[Serialization]属性存在时,我无法解决该怎么办?
我可以具有[Serialization]属性,并使JSON.Net使用构造函数吗?
如果您控制标记为
1 2 3 4 5 6 | [Serializable] [JsonObject] public class SerializableType { ... } |
然后从原始问题重新运行测试,您将为所有四个问题打" Hello"。
我制定了一个解决方案:
ReadAsAsync(http://msdn.microsoft.com/zh-cn/library/hh943959(v=vs.118).aspx)有一个替代,它允许您指定要显式使用的MediaTypeFormatter。
您可以通过更改" DefaultContractResolver"(http://james.newtonking.com/json/help/index.html?topic=html/SerializationAttributes.htm)上的属性IgnoreSerializationAttribute来指示JsonMediaTypeFormatter忽略[Serializable]属性。 。
将各个部分放在一起:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | private static void Main() { JsonMediaTypeFormatter mediaTypeFormatter = new JsonMediaTypeFormatter(); mediaTypeFormatter.SerializerSettings.ContractResolver = new DefaultContractResolver() { IgnoreSerializableAttribute = true }; String cargo ="Hello"; SerializableType serializableTypeOriginal = new SerializableType(cargo); String jsonFromSerializableType = JsonConvert.SerializeObject(serializableTypeOriginal); NonSerializableType nonSerializableTypeOriginalNonSerializableType = new NonSerializableType(cargo); String jsonFromNonSerializableType = JsonConvert.SerializeObject(nonSerializableTypeOriginalNonSerializableType); System.Diagnostics.Debug.Assert(jsonFromSerializableType == jsonFromNonSerializableType); HttpContent httpContent = new StringContent(jsonFromSerializableType, new UTF8Encoding(),"application/json"); SerializableType serializableTypeFromSerializableType = httpContent.ReadAsAsync<SerializableType>(new[] { mediaTypeFormatter }).Result; //serializableTypeFromSerializableType.A =="Hello" ? httpContent = new StringContent(jsonFromSerializableType, new UTF8Encoding(),"application/json"); NonSerializableType nonSerializableTypeFromSerializableType = httpContent.ReadAsAsync<NonSerializableType>(new[] { mediaTypeFormatter }).Result; //nonSerializableTypeFromSerializableType.A =="Hello" ? httpContent = new StringContent(jsonFromNonSerializableType, new UTF8Encoding(),"application/json"); SerializableType serializableTypeFromNonSerializableType = httpContent.ReadAsAsync<SerializableType>(new[] { mediaTypeFormatter }).Result; //serializableTypeFromNonSerializableType.A =="Hello" ? httpContent = new StringContent(jsonFromNonSerializableType, new UTF8Encoding(),"application/json"); NonSerializableType nonSerializableTypeFromNonSerializableType = httpContent.ReadAsAsync<NonSerializableType>(new[] { mediaTypeFormatter }).Result; //nonSerializableTypeFromNonSerializableType.A =="Hello" ? } |