JsonReader只读取字符串

时间:2017-12-07 22:14:31

标签: c# json websocket stream json.net

在我的场景中,两台服务器通过安全的WebSocket连接进行通信。已发送消息是明确定义的json对象。由于我正在处理WebSockets,我使用流将接收到的json反序列化为对象。

但是,在我的自定义转换器中,收到的json总是被反序列化为字符串类型的JValue。我花了大部分时间试图解决这个问题,并且最终必须将JValue转换为字符串,只是为了将其解析为JObject,而且 - 据我所知 - 完全否定了a的优点基于流的方法。

这是预期的行为吗?如果没有,我该如何解决这个问题?

这是有问题的代码。自定义序列化已在SerializerSettings对象中注册。

public Task ReceiveAsync(WebSocket socket, WebSocketReceiveResult result, byte[] buffer)
{
    SocketMessage message;
    try
    {
        var ser = JsonSerializer.Create(this.SerializerSettings);
        using (var sReader = new StreamReader(new MemoryStream(buffer)))
        {
            using (var jReader = new JsonTextReader(sReader))
            {
                message = ser.Deserialize<SocketMessage>(jReader);
            }
        }
    }
    catch (JsonReaderException jex)
    {
        this.Logger.LogError(1, jex, "Received json was not in the correct format.");
        return Task.FromException(jex);
    }
    //... Remainder removed for brevity
}


public class SocketMessage
{
    public SocketMessage()
    {
        this.Headers = new Dictionary<string, string>(5);
    }

    public IDictionary<string, string> Headers { get; set; }

    public JToken Content { get; set; }
}


public sealed class SocketMessageJsonConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(SocketMessage);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
        JsonSerializer serializer)
    {
        var jString = (string)JToken.ReadFrom(reader);
        var jVal = JObject.Parse(jString);

        var headers = jVal.Children<JProperty>()
            .Where(p => p.Name.Equals("headers", StringComparison.OrdinalIgnoreCase))
            .Values()
            .Children()
            .Select(c => c as JProperty)
            .Where(p => p != null)
            .ToDictionary(p => p.Name, p => (string)p.Value);

        return new SocketMessage
        {
            Headers = headers,
            Content = jVal["content"],
        };
    }
}

以下是收到的样本Json(使用Encoding.UTF8.GetString(buffer).TrimEnd('\0');Content属性是一个任意属性,它基于某些头字段,将在代码中的其他位置反序列化。因此,我只将其JObject存储为SocketMessage

  

@ “{”, “标题” “:{” “行动”, “:”, “打开”, “}”, “内容”, “:”, “地址”, “:”, “本地主机””, “” map_servers “”: []}}“

0 个答案:

没有答案