1

我有一个简单的项目,我正在使用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 编码。但这只发生在一个页面上,在另一个页面上,它按预期工作。

4

2 回答 2

1

综上所述,问题原来window.escape是被第三方 JS 库覆盖。这导致window.escape行为不同于“正常”,导致 SignalR 作为副作用失败。

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

于 2012-09-17T12:30:03.283 回答
-1

漏洞

我不知道这是否有帮助,但是当我尝试反序列化我的 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);

变量“内容”有时给我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。

于 2019-05-02T16:06:28.610 回答