SignalR返回错误 - 反序列化对象时意外结束

我有一个简单的项目,我正在使用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 Definitin

[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();
        });

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

EDIT 这是堆栈跟踪信息

[JsonSerializationException:反序列化对象时意外结束 . 第1行,位置2.] Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CheckedRead(JsonReader reader)75 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader,Type objectType,JsonContract contract,JsonProperty member,Object existingValue)48 Newtonsoft.Json .Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader,Type objectType,JsonContract contract,JsonProperty member,Object existingValue)86 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection wrappedList,JsonReader reader,String reference,JsonArrayContract contract)635 Newtonsoft.Json . 序列化 . <> c_DisplayClass1 . <CreateAndPopulateList> b_0(IList l,Boolean isTemporaryListReference)124 Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(Type listType,Action2 populateList)546 Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateAndPopulateList(JsonReader reader,String reference) ,J sonArrayContract 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成员,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,IEnumerable1 groups,IRequest request)140 SignalR.PersistentConnection.ProcessRequestAsync(HostContext context)227 SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext context)120 SignalR .Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase context)463 SignalR.Hosting.AspNet.HttpTaskAsyncHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context,AsyncCallback cb,Object 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

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

EDIT 3:

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

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

正如你所看到的,window.escape()负责编码connectionData,但是,如果我调试这个代码,我可以看到window.escape(connection.data)确实是html编码connection.data而不是url编码 . 但这只发生在一个页面上,而在其他页面上,它按预期工作 .

回答(1)

3 years ago

总而言之,问题结果是 window.escape 被第三方JS库覆盖了 . 这导致 window.escape 的行为与"normal"不同,导致SignalR作为副作用失败 .

基本上 - 当出现这些“怪异”问题时 - 检查是否包含了“干扰”的库并确保使用正确的命名空间(例如使用模块模式)来避免此问题 .