一个对象需要转成json 后转成byte[]后经过网络传输,后再次反序列化为对象,但是最后反序列的时候会报错,打印json发现开头是一个问号
使用这个进行反序列化
///
/// 反序列化方法
///
///
///
///
public static T Deserialize(string json) where T : Message, new()
{
return JsonConvert.DeserializeObject(json.TrimStart('\uFEFF'));
}
一个对象
using System.Threading;
namespace SocketTools
{
public class TextMessage : Message
{
private string message;
public string Message { get => message; set => message = value; }
public TextMessage()
{
}
public TextMessage(string userName, string targetName, string sendTime, string message) : base(userName, targetName, sendTime, MessageType.Text)
{
this.message = message;
}
}
父类
using Newtonsoft.Json;
namespace SocketTools
{
public enum MessageType
{
Connection = 0,
Text,
Image,
Mixed,
Recall,
File,
}
public class Message
{
private string userName;
private string targetName;
private string sendTime;
private MessageType messageType;
public string UserName { get => userName; set => userName = value; }
public string TargetName { get => targetName; set => targetName = value; }
public string SendTime { get => sendTime; set => sendTime = value; }
public MessageType MessageType { get => messageType; set => messageType = value; }
public Message()
{
}
public Message(string userName, string targetName, string sendTime, MessageType messageType)
{
UserName = userName;
TargetName = targetName;
SendTime = sendTime;
MessageType = messageType;
}
// 序列化方法
public static string Serialize(Message message)
{
return JsonConvert.SerializeObject(message);
}
// 反序列化方法
public static T Deserialize(string json) where T : Message, new()
{
return JsonConvert.DeserializeObject(json );
}
}
}
}
执行代码
using SocketTools;
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
namespace FunctionalTesting
{
internal class Program
{
private static void Main(string[] args)
{
string msg = "消息内容Q1_2_end";
string userName = "AAAAAAAAAAAAAAAA";
string targetUserName = "CCCCCCCCCCCCCCCC";
TextMessage textMessage = new TextMessage(userName,
targetUserName,
DateTime.Now.ToString("yy-MM-dd-H:m:s"),
msg);
// 按照指定的格式创建消息字符串
string message = Message.Serialize(textMessage);
Console.WriteLine(message);
// 将消息字符串转换为字节流
byte[] data;
using (MemoryStream ms = new MemoryStream())
{
using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8))
{
sw.Write(message);
sw.Flush();
ms.Position = 0;
data = ms.ToArray();
}
}
string data2 = Encoding.UTF8.GetString(data);
Console.WriteLine(data2);
data2 = Regex.Replace(data2, @"^\s+", "");
Console.WriteLine(data2);
var d = Message.Deserialize(data2);
Console.WriteLine(d.TargetName);
Console.WriteLine(d.UserName);
Console.WriteLine(d.MessageType);
Console.ReadLine();
}
}
}
执行之后会输出
?{"Message":"消息内容Q1_2_end","UserName":"AAAAAAAAAAAAAAAA","TargetName":"CCCCCCCCCCCCCCCC","SendTime":"23-12-04-1:14:43","MessageType":1}
错误日志:
Newtonsoft.Json.JsonReaderException
HResult=0x80131500
Message=Unexpected character encountered while parsing value: . Path '', line 0, position 0.
但是打印原本的数据是没有开头的问号的,
修改反序列化的代码,去除第一个前导字符即可,或者使用字符串的判断,如果第一个字符不是{
或者[
就去除第一个字符
// 反序列化方法
public static T Deserialize(string json) where T : Message, new()
{
return JsonConvert.DeserializeObject(json.TrimStart('\uFEFF'));
}
去除字符串
public static T Deserialize(string json) where T : Message, new()
{
if (json[0] == '{' || json[0] == '[')
{
}
else
{
json = json.Remove(0, 1);
}
return JsonConvert.DeserializeObject(json);
}
零宽度不中断空格(Unicode U+FEFF)字符,也称为 BOM(Byte Order Mark),在文本文件中用于表示字节顺序。它通常出现在使用 Unicode 编码的文本文件或数据流的开头。
在处理多字节编码时,需要知道每个字符的字节顺序。例如,在 UTF-16 编码中,一个字符由两个字节组成,而这两个字节的顺序可能会根据不同的系统和平台有所不同。为了明确表示字节顺序,引入了 BOM 字符。
BOM 字符 U+FEFF 可以作为文件的前导字符,允许解析器识别文件的字节顺序。当解析器遇到 U+FEFF 时,它可以确定字节顺序并正确地解码文件中的其余字符。
在某些情况下,尤其是在网络通信、数据库存储或其他形式的数据交换中,BOM 字符可能被无意间包含在字符串中,这可能导致解析错误。因此,有必要在处理这些字符串之前检查并移除任何不需要的 BOM 字符。