2

我已经查看并尝试了此处发布的每个解决方案,但均无济于事。

我的问题是:

  • 在 Web 解决方案(ASP.NET MVC 3 C#/Razor)上,我使用 Json.Net 序列化显示在某些报告上的数据,以便能够将其发送到 WPF 应用程序。这些报告结果是模型对象的集合。

  • 我在 WPF 应用程序上有相同的模型对象,所以当我反序列化 Json 字符串时,我想相应地绑定结果(保留原始模型对象)。

  • 每一端(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 应用程序,因为侦听器会期望来自许多报告的数据——这些报告是不同模型的集合。所以,当绑定回来时,我知道应该绑定哪个对象。

4

1 回答 1

3

我坚持我最初的答案-序列化数据中的类型信息真的很混乱-最好将代码更改为不需要它,而是“修复”它(不确定这是正确的词)-仔细查看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; }
    }
}
于 2013-07-05T10:07:29.370 回答