3

我对 SignalR 有一个奇怪的问题,我有一个简单的集线器,它接受这样的模型:

public class Entry
{
    public string Version { get; set; }

    public Guid PersistedId
    {
        get { return Id; }
        set { Id = value; }
    }

    public Guid Id { get; set; }
    public Guid ParentId { get; set; }

    [Required]
    public string Content { get; set; }

    public DateTime DateCreated { get; set; }
    public Guid CreatorAccountId { get; set; }
}

然后我查看请求对象,转到服务器的帖子是:

{"H":"entryhub","M":"SendEntry","A":["{\"Version\":\"1.0.0\",\"PersistedId\":\"00000000-0000-0000-0000-000000000000\",\"ParentId\":\"1764a2e3-ff6f-4a17-9c5f-d99642301dbf\",\"Content\":\"test\",\"DateCreated\":\"2013-07-21T14:06:01.980Z\",\"CreatorAccountId\":\"00000000-0000-0000-0000-000000000000\"}"],"I":2}

我不断收到回复,但有以下例外:

{"I":"2","E":"Error converting value \"{\"Version\":\"1.0.0\",\"PersistedId\":\"00000000-0000-0000-0000-000000000000\",\"ParentId\":\"1764a2e3-ff6f-4a17-9c5f-d99642301dbf\",\"Content\":\"test\",\"DateCreated\":\"2013-07-21T14:06:01.980Z\",\"CreatorAccountId\":\"00000000-0000-0000-0000-000000000000\"}\" to type 'SharedPlugin.Models.Entry'. Path '', line 1, position 266.","T":"   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.EnsureType(JsonReader reader, Object value, CultureInfo culture, JsonContract contract, Type targetType)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue)\r\n   at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent)\r\n   at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.Deserialize(TextReader reader, Type objectType)\r\n   at Microsoft.AspNet.SignalR.Json.JRawValue.ConvertTo(Type type)\r\n   at Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver.ResolveParameter(ParameterDescriptor descriptor, IJsonValue value)\r\n   at System.Linq.Enumerable.<ZipIterator>d__7a`3.MoveNext()\r\n   at System.Linq.Buffer`1..ctor(IEnumerable`1 source)\r\n   at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)\r\n   at Microsoft.AspNet.SignalR.Hubs.DefaultParameterResolver.ResolveMethodParameters(MethodDescriptor method, IList`1 values)\r\n   at Microsoft.AspNet.SignalR.Hubs.HubDispatcher.InvokeHubPipeline(IHub hub, IJsonValue[] parameterValues, MethodDescriptor methodDescriptor, HubRequest hubRequest, StateChangeTracker tracker)"}

现在我想可能是 Json.net 的底层序列化存在问题,但是我编写了一个单元测试,从 post 请求中获取完全相同的 json 字符串,并将其反序列化为一个 Entry 对象,它工作正常。

我在网上查过,但似乎没有太多关于错误的信息。我认为它可能是日期,但尝试设置我自己的 JsonNetSerializer` 并更改它处理日期、空值、缺少成员等的方式,但是似乎没有任何帮助,并且在单元测试中它除了默认值和工作正常,所以这意味着它不是 Json.net 的问题。

4

1 回答 1

0

发现了问题,它归结为双重序列化,因为我在我的对象上调用 ko.toJSON 而不是 ko.toJS。

ko.toJSON — 这会生成一个 JSON 字符串,代表您的视图模型的数据。在内部,它只是在视图模型上调用 ko.toJS,然后在结果上使用浏览器的原生 > JSON 序列化程序。注意:要在没有原生 JSON > 序列化程序的旧浏览器(例如,IE 7 或更早版本)上运行,您还必须引用 json2.js 库。

ko.toJS - 这会克隆你的视图模型的对象图,用 > 当前值替换每个可观察的可观察的,所以你得到一个纯副本,其中只包含你的数据,不包含与淘汰相关的工件

只有在与 dfowler 交谈后,我才意识到情况确实如此,并且请求数据将 json 显示为单个字符串,而不是预期的完整 json 对象。所以不要双重序列化!

于 2013-07-21T18:06:52.713 回答