我有一个简单的项目,我正在使用signalR,当页面加载时,signalR脚本成功加载,但在此之后,调用
的http://本地主机:24634 / signalr / signalr /连接运输= foreverFrame&安培;的ConnectionId = dca2db9c-B16A-4b96-96dc-9a6b187b6d9e&安培; connectionData = [{ “名称”: “通知”}]&安培; 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();
});
任何想法可能导致此错误?
修改 这是堆栈跟踪信息
[JsonSerializationException:反序列化对象时意外结束。 第1行,第2位。]
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CheckedRead(JsonReader 读者)+75
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader,Type objectType,JsonContract契约,JsonProperty成员, 对象existingValue)+48
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader,Type objectType,JsonContract契约,JsonProperty成员, Object existingValue)+86
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection wrappedList,JsonReader reader,String reference,JsonArrayContract 合同)+635
Newtonsoft.Json.Serialization<> C_ DisplayClass1< CreateAndPopulateList&GT,B _0(IList的 l,Boolean isTemporaryListReference)+124
Newtonsoft.Json.Utilities.CollectionUtils.CreateAndPopulateList(类型 listType,Action2 populateList) +546
1组,IRequest request)+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 context) +227 SignalR.Hubs.HubDispatcher.ProcessRequestAsync(HostContext context)+120
SignalR.Hosting.AspNet.AspNetHandler.ProcessRequestAsync(HttpContextBase 上下文)+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:
还有一个注意事项 - 从运行的页面中没有任何错误,请求的网址看起来像这样
本地主机:24634 / signalr / signalr /连接运输= foreverFrame&安培;的ConnectionId = 98e6d5b3-b164-4013-92c2-418aa6254f9e&安培; connectionData =%5B%7B%22name%22%3A%22notifier%22%7D%5D&安培; TID = 7&安培; frameId = 1
并且失败的请求网址看起来像这样
本地主机:24634 / signalr / signalr /连接运输= foreverFrame&安培;的ConnectionId = 9b398750-99d6-4188-88b5-b41ad9eb82d5&安培; connectionData = [{ “名称”: “通知”}]&安培; TID = 1&安培; frameId = 1
您可能会注意到,在URL中定义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编码。但这只发生在一个页面上,在其他页面上,它按预期工作。
答案 0 :(得分:1)
总而言之,问题是window.escape
被第三方JS库覆盖了。这导致window.escape
的行为与“正常”不同,导致SignalR作为副作用失败。
基本上 - 当出现这些“奇怪”问题时 - 检查是否包含了“干扰”的库并确保使用正确的命名空间(例如使用模块模式)来避免此问题。
答案 1 :(得分:-1)
BUG
我不知道这是否有帮助,但是当我尝试反序列化json时,出现错误“反序列化对象消息c#时意外结束”。 有时是发生在我身上,有时不是。我不知道这取决于什么。
我的json是这样的:
https://api.myjson.com/bins/l83m8
在Visual Studio 2019上调试Xamarin App给我以下内容:
var content = await _client.GetStringAsync(Connection.URL);
invitaciones = JsonConvert.DeserializeObject<RootObject>(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。