我有一个简单的项目,我正在使用signalR,当页面加载时,signalR脚本被成功加载,但是在那之后,调用
http://localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=dca2db9c-b16a-4b96-96dc-9a6b187b6d9e&connectionData=[{"name":"notifier"}]&tid=5&frameId=1
返回 500 Internal Server Error,我在 fiddler 中检查了这个请求,错误消息说
反序列化对象时意外结束。
这是我的集线器定义
[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 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.Serialization.<>c_ DisplayClass1.<CreateAndPopulateList>b _0(IList l, Boolean isTemporaryListReference) +124
Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(Type listType, Action 1 groups, IRequest request) +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 context, AsyncCallback cb, Object extraData) +682 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
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
编辑2:
还有一点注意 - 从运行没有任何错误的页面中,请求的 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 编码。但这只发生在一个页面上,在另一个页面上,它按预期工作。