我正在使用DataContractJsonSerializer
来序列化对象,并且为此,我正在使用以下函数:
public static string Serialize<T>(T obj)
{
string returnVal = "";
try
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
returnVal = Encoding.UTF8.GetString(ms.ToArray());
}
}
catch (Exception /*exception*/)
{
returnVal = "";
//log error
}
return returnVal;
}
现在,此功能运行良好且很好 ...除了在以下情况下(除非您更改此值,我认为这很有意义,因为我不知道它会如何影响我的其他人代码)。
无法正常运行的情况
说我有 obj (参数)一个对象,例如:
[DataContract()]
public class theObject
{
[DataMember()]
public string image;
}
其中image
保存BMP文件的Base64值。
这是一个很大的值,但是例如,它的开头为:"Qk1W/QAAAAAAADYAAAAoAAAAawAAAMgAAAABABgAAAAAACD9AADEDgAAxA4AAAAAAAAAAAAA////////////////////////////////////7+/...."
因此,您看到它包含很多/
。
因此,当我将此对象传递给Serialize
时,它将以毫秒为单位WriteObject
,然后将其放入一个数组中,最后将到达returnVal
。
现在让我们检查一下returnVal
。它为JSON格式(正确),当您将其可视化为JSON时,它将向您显示:
image:"Qk1W/QAAAAAAADYAAAAoAAAAawAAAMgAAAABABgAAAAAACD9AADEDgAAxA4AAAAAAAAAAAAA////////////////////////////////////7+/...."
但是!当您将其可视化为文本时,它将向您显示:
"image":"Qk1W\/QAAAAAAADYAAAAoAAAAawAAAMgAAAABABgAAAAAACD9AADEDgAAxA4AAAAAAAAAAAAA\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/7+\/..."
您看到了吗?它在每个\
之前插入了/
,这有很大的不同。
所以我的问题是:
/
s)编辑:
尽管可以说\/
和/
是相同的,但后果却不一样。稍后,当使用此JSON通过
byte[] bytes = Encoding.UTF8.GetBytes(json);
ByteArrayContent byteContent = new ByteArrayContent(bytes);
byteContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue(content);
添加了\
的版本将导致bytes
包含115442字节,而仅使用/
的版本将导致bytes
包含86535字节。因此结果是完全不同的。
那么,如何在不添加\
的情况下获得结果?
答案 0 :(得分:1)
DataContractJsonSerializer
的标准行为是转义字符串中的/
个字符,以便它们在JSON中成为\/
。当将JSON反序列化回对象时,\/
转义序列将转回/
,因此不会丢失或破坏任何数据。 (尝试一下,看看。)但是,确实会导致更大的JSON大小(以字节为单位)。如果这确实是您的问题,可以采取一些措施来解决:
方法1
序列化后,您可以立即使用string.Replace()
来消除所有直接出现在斜杠前的反斜杠。您可以通过更改以下行,在您的Serialize
方法中执行此操作:
returnVal = Encoding.UTF8.GetString(ms.ToArray());
对此:
returnVal = Encoding.UTF8.GetString(ms.ToArray()).Replace("\\/", "/");
由于/
在JSON中没有特殊含义,因此实际上不必使用\
对其进行转义,尽管这样做是允许的。 (请参见JSON specification的第5页。)DataContractJsonSerializer
仍会反序列化JSON,即使斜杠未转义也是如此。 (您自己尝试一下,看看。我会为此摆弄,但是.NET Fiddle不支持DataContractJsonSerializer
)。
方法2 (推荐)
切换到更好的JSON序列化程序,例如Json.Net,该序列化程序首先不会转义斜杠。您可以简化代码并将整个Serialize
方法替换为JsonConvert.SerializeObject()