我已经查看并尝试了这里发布的每一个解决方案,但都没有成功。
我的问题是:
-
在一个web解决方案(ASP.NET MVC 3 C#/Razor)上,我使用Json.NET序列化一些报表上显示的数据,以便能够将其发送到WPF应用程序。这些报告结果是模型对象的集合。
-
我在WPF应用程序上有相同的Model对象,所以当我反序列化Json字符串时,我希望相应地绑定结果(保留原始Model对象)。
-
程序集名称和对象类型在每一端都不同(Web/App)-不同的命名空间。
以下是我迄今为止所尝试的:
网上解决方案:
// MyModel
public class MyModel
{
public long Id { get; set; }
public string Name { get; set; }
}
// data = IEnumerable<MyModel>
var jsonData = JsonConvert.SerializeObject(data.ToArray(), data.ToArray().GetType(),
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
在应用程序上:
// MyModel
public class MyModel
{
[JsonProperty("Id")]
public long Id { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
}
var jsonArray = JsonConvert.DeserializeObject(e.jsonObject,
null,
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All,
Binder = new MySerializationBinder()
});
public class MySerializationBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
return typeof(MyModel);
}
}
有人能帮我一下吗?
谢谢!
更新
根据@Marc Gravell评论:
我忘了在这里提到主要问题。我需要将Object类型发送到WPF应用程序,因为侦听器将期望来自许多报告的数据,这些报告是不同模型的集合。所以,当把它绑定回来时,我知道应该绑定哪个Object。
我坚持我最初的答案-序列化数据中的类型信息真的很混乱-最好更改代码,不需要这个,而是"修复"它(不确定这个词是正确的)-仔细看typeName
-它并不总是你所期望的:
public class MySerializationBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
switch(typeName)
{
case "WebSolution.MyModel[]": return typeof(Application.MyModel[]);
case "WebSolution.MyModel": return typeof(Application.MyModel);
default: return base.BindToType(assemblyName, typeName);
}
}
}
顺便说一句,一旦知道了数组类型,元素类型就是隐式的——所以只包括数组类型就可以节省一些精力:
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Arrays
}
但我还是建议:不要这样做。
这里的"错误"是首先包含了完整的类型名称;json中类型名称的存在通常应该是代码气味的警告信号。删除这些,没有什么可做的-它只起作用:
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Linq;
static class Program
{
static void Main()
{
// here imagine we're in the web tier, serializing
var data = GetData();
var jsonData = JsonConvert.SerializeObject(
data.ToArray(), Formatting.None);
// now imagine we're at the application, deserializing
var appData = JsonConvert.DeserializeObject<Application.MyModel[]>(
jsonData);
// and it all works fine
}
static IEnumerable<WebSolution.MyModel> GetData()
{
yield return new WebSolution.MyModel { Id = 123, Name = "abc" };
yield return new WebSolution.MyModel { Id = 456, Name = "def" };
}
}
namespace WebSolution
{
// MyModel
public class MyModel
{
public long Id { get; set; }
public string Name { get; set; }
}
}
namespace Application
{
// MyModel
public class MyModel
{
[JsonProperty("Id")]
public long Id { get; set; }
[JsonProperty("Name")]
public string Name { get; set; }
}
}