[英]Problem when serializing objects with strings that contain "/"
我正在使用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+/...."
所以你看到它包含了很多/
s。
因此,當我將此對象傳遞給Serialize
,它將在 ms 中WriteObject
,然后將其放入一個數組中,該數組最終將轉到returnVal
。
現在讓我們檢查returnVal
。 它采用 JSON 格式(正確),當您將其可視化為 JSON 時,它將顯示:
image:"Qk1W/QAAAAAAADYAAAAoAAAAawAAAMgAAAABABgAAAAAACD9AADEDgAAxA4AAAAAAAAAAAAA////////////////////////////////////7+/...."
然而! 當您將其可視化為文本時,它將顯示:
"image":"Qk1W\/QAAAAAAADYAAAAoAAAAawAAAMgAAAABABgAAAAAACD9AADEDgAAxA4AAAAAAAAAAAAA\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/7+\/..."
你看到嗎? 它在每個/
之前插入了\\
並且有很大的不同。
所以我的問題是:
/
s)編輯:
雖然可以說\\/
和/
是一樣的,但結果卻不是。 稍后使用此 JSON 將其拋出到 Web Api 時使用
byte[] bytes = Encoding.UTF8.GetBytes(json);
ByteArrayContent byteContent = new ByteArrayContent(bytes);
byteContent.Headers.ContentType = new MediaTypeWithQualityHeaderValue(content);
版本與添加\\
導致bytes
與115442個字節而版本僅使用/
在結果中bytes
的86535個字節。 因此結果大不相同。
那么如何在不添加\\
s 的情況下獲得結果?
DataContractJsonSerializer
的標准行為是轉義字符串中的/
字符,使它們在 JSON 中變為\\/
。 當 JSON 反序列化回對象時, \\/
轉義序列將轉回/
因此不會丟失或損壞數據。 (試試看。)但是它確實會導致更大的 JSON 大小(以字節為單位)。 如果這真的是您的問題,您可以采取以下措施來解決它:
方法一
序列化后,您可以立即使用string.Replace()
去除直接出現在斜杠之前的所有反斜杠。 您可以通過更改以下行在Serialize
方法中正確執行此操作:
returnVal = Encoding.UTF8.GetString(ms.ToArray());
對此:
returnVal = Encoding.UTF8.GetString(ms.ToArray()).Replace("\\/", "/");
因為/
在 JSON 中沒有特殊含義,所以實際上沒有必要用\\
對它們進行轉義,盡管這樣做是允許的。 (請參閱JSON 規范的第 5 頁。)即使沒有轉義斜杠, DataContractJsonSerializer
仍然可以很好地反序列化 JSON。 (自己試試看。我會為此做一個小提琴,但.NET Fiddle不支持DataContractJsonSerializer
)。
方法二(推薦)
切換到更好的 JSON 序列化程序,例如Json.Net ,它首先不會轉義斜杠。 您可以簡化代碼並使用JsonConvert.SerializeObject()
替換整個Serialize
方法
小提琴: https : //dotnetfiddle.net/MQKXSD
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.