// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.md in the project root for license information. using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using Microsoft.AspNet.SignalR.Json; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Microsoft.AspNet.SignalR.Hubs { internal class HubRequestParser : IHubRequestParser { private static readonly IJsonValue[] _emptyArgs = new IJsonValue[0]; public HubRequest Parse(string data) { var serializer = new JsonNetSerializer(); var deserializedData = serializer.Parse(data); var request = new HubRequest(); request.Hub = deserializedData.Hub; request.Method = deserializedData.Method; request.Id = deserializedData.Id; request.State = GetState(deserializedData); request.ParameterValues = (deserializedData.Args != null) ? deserializedData.Args.Select(value => new JRawValue(value)).ToArray() : _emptyArgs; return request; } [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "This type is used for deserialzation")] private class HubInvocation { [JsonProperty("H")] public string Hub { get; set; } [JsonProperty("M")] public string Method { get; set; } [JsonProperty("I")] public string Id { get; set; } [JsonProperty("S")] public JRaw State { get; set; } [JsonProperty("A")] public JRaw[] Args { get; set; } } private static IDictionary GetState(HubInvocation deserializedData) { if (deserializedData.State == null) { return new Dictionary(); } // Get the raw JSON string and check if it's over 4K string json = deserializedData.State.ToString(); if (json.Length > 4096) { throw new InvalidOperationException(Resources.Error_StateExceededMaximumLength); } var settings = new JsonSerializerSettings(); settings.Converters.Add(new SipHashBasedDictionaryConverter()); var serializer = new JsonNetSerializer(settings); return serializer.Parse>(json); } } }