【发布时间】: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) +5461 组,IRequest 请求)+140
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
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