我有一个接口(interface),公开了一个名为 Pages
的属性:
public interface INameSet
{
IQueryable<string> Names { get; }
}
我有一个实现接口(interface)的类,并且还必须从 JSON 对象解析:
[DataContract(Name = "surveyPageSet")]
public class SurveyPage : INameSet
{
[DataMember(Name = "names")]
public List<string> SurveyNames { get; set; }
public IQueryable<string> Names
{
get
{
//Returns SurveyNames after some filtration logic
}
}
}
我的问题是,当我传入这个对象时:
{
"names": ["testname"]
}
JSON 解释器正在尝试反序列化它以匹配 Names
属性而不是 SurveyNames
属性。我知道会发生这种情况,因为当删除接口(interface)的实现并将 SurveyNames
更改为 Names
时,它会很好地填充属性。有没有办法让它序列化到正确的属性,或者我是否需要创建一个翻译器类来生成 INameSet
接口(interface)的正确具体?
编辑:这是使用内置序列化器的。如果 Newtonsoft/JSON.NET 有一个解决方案,那对我来说就很好。
最佳答案
JavaScriptSerializer
不允许重新映射开箱即用的名称,因此请勿使用它。
相反,请使用 Json.NET或 DataContractJsonSerializer。事实上,考虑到您应用的数据协定属性,两者都应该已经工作。
例如,使用 Json.NET,如果我这样做:
var page1 = JsonConvert.DeserializeObject<SurveyPage>(json);
Debug.Assert(page1.SurveyNames != null && page1.SurveyNames.SequenceEqual(new string [] { "testname" }));
然后就没有断言了。同样,如果我这样做,也没有断言:
var page2 = DataContractJsonSerializerHelper.GetObject<SurveyPage>(json);
Debug.Assert(page2.SurveyNames != null && page2.SurveyNames.SequenceEqual(new string[] { "testname" }));
使用辅助类:
public static class DataContractJsonSerializerHelper
{
private static MemoryStream GenerateStreamFromString(string value)
{
return new MemoryStream(Encoding.Unicode.GetBytes(value ?? ""));
}
public static string GetJson<T>(T obj, DataContractJsonSerializer serializer)
{
using (var memory = new MemoryStream())
{
serializer.WriteObject(memory, obj);
memory.Seek(0, SeekOrigin.Begin);
using (var reader = new StreamReader(memory))
{
return reader.ReadToEnd();
}
}
}
public static string GetJson<T>(T obj) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return GetJson(obj, serializer);
}
public static T GetObject<T>(string json) where T : class
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
return GetObject<T>(json, serializer);
}
public static T GetObject<T>(string json, DataContractJsonSerializer serializer)
{
T obj = default(T);
using (var stream = GenerateStreamFromString(json))
{
obj = (T)serializer.ReadObject(stream);
}
return obj;
}
}
更新
如果你确实想继续使用JavaScriptConverter
,你可以自己编写JavaScriptConverter
并手动反序列化每个字段。但这很麻烦,我不推荐它。
关于c# - 使用不同的名称反序列化属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28288034/