在我的场景中,两台服务器通过安全的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 “”: []}}“