[英]Serialize C# objects to a JSON to a server
我尝试将 C# 对象序列化为 JSON 字符串,然后通过网络将其发送到服务器。 然而,服务器永远不会得到对象。 我尝试通过将 TypeNamehandling 设置为 Obejcts 来使用 JsonSerializer 的设置,但这也不起作用。 我也不喜欢将 JSON-String 转换为字节并以这种方式发送,因为我需要找到一些方法来刷新我正在使用的 NetworkStream,目前这个 Stream 始终是打开的。
我在网上找不到任何解决方案。 我希望这里有人可以帮助我。 整个代码上传到我的 GitHub!
我的客户代码:
public void Serialize(object value)
{
StreamWriter streamWriter = new StreamWriter(Stream);
JsonWriter jsonWriter = new JsonTextWriter(streamWriter);
jsonSerializer.Serialize(jsonWriter, value,typeof(Message));
}
public Message Deserialize()
{
StreamReader streamReader = new StreamReader(Stream);
JsonReader jsonReader = new JsonTextReader(streamReader);
return jsonSerializer.Deserialize<Message>(jsonReader);
}
我的服务器代码
public void Serialize(Stream stream, object value)
{
StreamWriter streamWriter = new StreamWriter(stream);
JsonWriter jsonWriter = new JsonTextWriter(streamWriter);
jsonSerializer.Serialize(jsonWriter, value,typeof(Message));
}
public Message Deserialize(Stream stream)
{
StreamReader streamReader = new StreamReader(stream);
JsonReader jsonReader = new JsonTextReader(streamReader);
return jsonSerializer.Deserialize<Message>(jsonReader);
}
一条消息 object 看起来像这样
[Serializable]
public class StartupMessage : Message
{
public string Username { get; set; }
public StartupMessage(string username)
{
Username = username ?? throw new ArgumentNullException(nameof(username));
}
}
编辑:来自我的客户的更多代码,显示了我发送对象的方式和方式:
public string Username { get; }
public string ServerIP { get; }
//private readonly BinaryFormatter Formatter;
private readonly JsonSerializer jsonSerializer;
private readonly TcpClient Server;
private readonly NetworkStream Stream;
public event EventHandler<NewMessageEventArgs> NewMessage;
public Client(string username, string serverIP)
{
Username = username ?? throw new ArgumentNullException(nameof(username));
ServerIP = serverIP ?? throw new ArgumentNullException(nameof(serverIP));
//Formatter = new BinaryFormatter();
Server = new TcpClient(ServerIP, Message.Port);
Stream = Server.GetStream();
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Objects
};
jsonSerializer = JsonSerializer.Create(settings);
}
public void Start()
{
Serialize(new StartupMessage(Username));
var recieverThread = new Thread(() =>
{
while (true)
{
Message msg = Deserialize();
if(msg is ConnectedMessage)
{
Console.WriteLine("Connected!");
}
if(msg is MessageMessage message)
{
OnNewMessage(new NewMessageEventArgs(message.Message, message.Username));
}
}
});
recieverThread.Start();
}
编辑 2 :
private readonly List<ClientInfo> clientInfos;
//private readonly BinaryFormatter formatter;
private readonly TcpListener tcpListener;
private readonly JsonSerializer jsonSerializer;
public EventHandler<NewMessageEventArgs> NewMessage;
public Server()
{
clientInfos = new List<ClientInfo>();
//formatter = new BinaryFormatter();
tcpListener = new TcpListener(IPAddress.Any, Message.Port);
var settings = new JsonSerializerSettings()
{
TypeNameHandling = TypeNameHandling.Objects
};
jsonSerializer = JsonSerializer.Create(settings);
}
public void Start()
{
while (true)
{
tcpListener.Start();
TcpClient client = tcpListener.AcceptTcpClient();
var recieverThread = new Thread(() =>
{
NetworkStream stream = client.GetStream();
while (true)
{
Message msg = Deserialize(stream);
if (msg is StartupMessage startup)
{
OnNewMessage(new NewMessageEventArgs("CONNECTED", startup.Username),true);
string username = startup.Username;
clientInfos.Add(new ClientInfo(username, stream));
Serialize(stream, new ConnectedMessage());
}
if (msg is MessageMessage message)
{
OnNewMessage(new NewMessageEventArgs(message.Message, message.Username),false);
foreach (ClientInfo info in clientInfos)
{
Serialize(info.Stream, message);
}
}
}
});
recieverThread.Start();
}
}
找到了解决方案。 问题是,如果正在发送数据,我的客户端从未真正发送过 JSON 数据,而我的服务器无法真正接收到它。
解决方案相当简单。 我只是使用StreamWriter
发送转换后的 object。 我使用WriteLine
函数很重要,因为它在 package 的末尾添加了Environment.NewLine
标记,向服务器显示这是包的结尾!
public void Serialize(Stream stream, Message value)
{
using (StreamWriter streamWriter = new StreamWriter(stream))
{
string json = JsonConvert.SerializeObject(value);
streamWriter.WriteLine(json);
}
}
对于接收部分,我将StreamReader
与 function ReadLine
一起使用。 这个 function 读取StreamReader
中使用的 stream 直到它看到Environment.NewLine
-mark。
public Message Deserialize(Stream stream)
{
using (StreamReader streamReader = new StreamReader(stream, true))
{
JsonReader jsonReader = new JsonTextReader(streamReader);
string json = streamReader.ReadLine();
return JsonConvert.DeserializeObject<Message>(json);
}
}
唯一的问题是, JsonConvert.DeserializeObject
函数不会反序列化抽象对象或接口。 为此,您可以观看此帖子!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.