私はsignalRを使用している単純なプロジェクトを持っています。ページが読み込まれると、signalRスクリプトが正常に読み込まれますが、その直後に
http://localhost:24634/signalr/signalr/connect?transport=foreverFrame&connectionId=dca2db9c-b16a-4b96-96dc-9a6b187b6d9e&connectionData=[{"name":"notifier"}]&tid=5&frameId=1
500 内部サーバー エラーを返します。フィドラーでこの要求を確認しました。エラー メッセージは次のように表示されます
オブジェクトの逆シリアル化中に予期しない終了が発生しました。
これが私のハブ定義です
[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
。 .Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader リーダー、Type objectType、JsonContract コントラクト、JsonProperty メンバー、Object existingValue) +86
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IWrappedCollection ラップリスト、JsonReader リーダー、文字列参照、JsonArrayContract コントラクト) +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 コンテキスト、AsyncCallback cb、オブジェクト 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
EDIT2:
もう 1 つ注意 - エラーなしで実行されるページから、要求された 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
お気づきかもしれませんが、connectionData クエリ文字列パラメータが URL で定義される方法が異なります。特に、最初の URL では、connectionData はクエリ文字列値を URL エンコードし、2 番目のクエリ文字列パラメータは html エンコードされています。リクエスト ヘッダーを調べましたが、失敗したリクエストの Content-Type は text/html で、2 番目のリクエストの 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) が url エンコードではなく connection.data をエンコードしていることがわかります。しかし、これはあるページでのみ発生しており、別のページでは期待どおりに機能します。