【问题标题】:SignalR returns error - Unexpected end when deserializing objectSignalR 返回错误 - 反序列化对象时意外结束
【发布时间】:2012-09-14 08:07:00
【问题描述】:

我有一个简单的项目,我正在使用 signalR,当页面加载时,signalR 脚本被成功加载,但是在那之后,调用

http://localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=dca2db9c-b16a-4b96-96dc-9a6b187b6d9e&connectionData=[{"name":"notifier"}]&tid=5&frameId=1

返回 500 内部服务器错误,我在 fiddler 中检查了这个请求,错误消息说

反序列化对象时意外结束。

这是我的 Hub 定义

[HubName("notifier")]
    public class PublishingNotifier: Hub
    {   
        [HubMethodName("send")]
        public void SendMessage(string message)
        {
            Clients.getNotification(message);
        }
    }

这是我的客户端代码

$(function () {

            var publishingNotifier = $.connection.notifier;

            publishingNotifier.getNotification = function (message) {
                // do something
            };

            $('input[type=submit][id*=cmsB_ChangeStatusToPublishedTop]').on('click', function (e) {
                // do something else
            });

            $.connection.hub.start();
        });

任何想法可能导致此错误?

编辑 这是堆栈跟踪信息

[JsonSerializationException:反序列化对象时意外结束。 第 1 行,位置 2。]
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CheckedRead(JsonReader 读者)+75
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, 对象现有值)+48
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, 对象现有值)+86
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection WrappedList、JsonReader 阅读器、字符串引用、JsonArrayContract 合同)+635
Newtonsoft.Json.Serialization.c_DisplayClass1.b_0(IList l, Boolean isTemporaryListReference) +124
Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(类型 listType,Action2 populateList) +546
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList(JsonReader reader, String reference, JsonArrayContract contract) +101
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String reference) +62
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue) +113
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueNonProperty(JsonReader reader, Type objectType, JsonContract contract, JsonConverter converter) +118
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType) +125
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) +311
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) +107
Newtonsoft.Json.JsonConvert.DeserializeObject(String value, JsonSerializerSettings settings) +66
SignalR.JsonNetSerializer.Parse(String json) +57
SignalR.Hubs.HubDispatcher.CreateConnection(String connectionId, IEnumerable
1 组,IRequest 请求)+140
SignalR.PersistentConnection.ProcessRequestAsync(HostContext 上下文) +227 SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext 上下文)+120
SignalR.Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase 上下文)+463
SignalR.Hosting.AspNet.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext 上下文,AsyncCallback cb,对象 extraData)+68
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

EDIT2:

另外一点 - 从运行时没有任何错误的页面来看,请求的 url 看起来像这样

localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=98e6d5b3-b164-4013-92c2-418aa6254f9e&connectionData=%5B%7B%22name%22%3A%22notifier%22%7D%5D&tid=7&frameId=1

失败的请求 url 看起来像这样

localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=9b398750-99d6-4188-88b5-b41ad9eb82d5&connectionData=[{"name":"notifier"}]&tid=1&frameId=1

你可能注意到,urls中定义connectionData查询字符串参数的方式是不同的,特别是对于第一个url,connectionData是url编码的查询字符串值,第二个查询字符串参数是html编码的。我查看了请求标头,失败的请求 Content-Type 是 text/html,第二个请求的 Content-Type:application/json。

编辑 3:

我在 jquery.signalR-0.5.3.js 文件中找到了 connectionData 的解析位置,这里是实际编码 connectionData 值的代码

if (connection.data) {
  qs += "&connectionData=" + window.escape(connection.data);
}

如您所见,window.escape() 负责对 connectionData 进行编码,但是,如果我调试此代码,我可以看到 window.escape(connection.data) 确实是 html 编码 connection.data 而不是 url 编码。但这仅在一个页面上发生,在另一个页面上,它按预期工作。

【问题讨论】:

  • 异常究竟是什么时候发生的?您是从客户端调用服务器端 SendMessage 集线器方法,还是?
  • 不,我什么都不做,只是在等待页面加载。在提琴手中,我可以看到该页面无法发出 signalR 请求,此外,我必须在几个页面上具有此逻辑(客户端),而这种类型的异常仅发生在其中一个页面上。
  • 从我在各种类似问题中看到的内容来看,人们一直在使用 Newtonsoft JSON 序列化程序时遇到问题 - 您可以尝试安装新版本或旧版本,看看是否有什么不同。此外,您确定不能在任何客户端上重现此错误吗?客户端使用哪些浏览器?您在浏览器的控制台中看到任何错误吗?
  • 嗯,实际上我尝试重新安装 Newtonsoft,甚至尝试了不同的版本,但没有任何帮助。我无法重现这个,我创建了类似的项目,它按预期运行。正如我所提到的,这个完全相同的代码在同一个项目的另一个页面上工作,但是在这个页面上,它失败了。问题是,我看不到谁调用 JSON.NET API(如堆栈跟踪中所见)以某种方式更清楚地了解可能导致问题的原因。并且控制台没有任何错误信息,我尝试了所有主流浏览器(IE9+、Chrome/Firefox),结果都一样。
  • SignalR 怎么样 - 你尝试过他们的客户端库的哪些版本?

标签: signalr signalr-hub


【解决方案1】:

总结一下,问题原来是window.escape被第三方JS库覆盖了。这导致 window.escape 的行为与“正常”不同,从而导致 SignalR 作为副作用失败。

所以基本上——当这些“奇怪”问题发生时——检查你是否包含了“干扰”的库,并确保使用正确的命名空间(例如使用模块模式)来避免这个问题。

【讨论】:

    【解决方案2】:

    错误

    我不知道这是否有帮助,但是当我尝试反序列化我的 json 时,出现错误“反序列化对象消息 c# 时出现意外结束”。 它有时会发生在我身上,有时不会。我不知道它取决于什么。

    我的 json 是这样的:

    https://api.myjson.com/bins/l83m8

    在 Visual Studio 2019 上调试 Xamarin 应用程序为我提供以下信息:

    var content = await _client.GetStringAsync(Connection.URL);
    invitaciones = JsonConvert.DeserializeObject<RootObject>(content);
    

    变量“content”有时给我https://textsaver.flap.tv/lists/2lss,有时给我https://textsaver.flap.tv/lists/2lsu

    如果你仔细看,你会发现两者是不同的,只是因为,第一个最后少了一个 }。

    如果您使用https://www.unserialize.me/ 工具对两者进行反序列化,然后在https://jsonformatter.curiousconcept.com/ 上验证结果(默认选项),您将看到第一个无效,而第二个有效。

    解决方案:

    添加验证:如果字符串内容 (json) 不以 } 结尾,则在末尾加上 }。我知道这很愚蠢,但解决了我的问题。

     var content = await _client.GetStringAsync(Connection.URL);
     if (!content.EndsWith("}"))
         content = content + "}";
     invitaciones = JsonConvert.DeserializeObject<RootObject>(content);
    

    包:Newtonsoft.Json 12.0.2、Xamarin.Forms 3.6.0.344457。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-13
      • 1970-01-01
      • 2018-12-08
      • 2016-12-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多