簡體   English   中英

使用包含“/”的字符串序列化對象時出現問題

[英]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+\/..."

你看到嗎? 它在每個/之前插入了\\並且有很大的不同。

所以我的問題是:

  1. 為什么將其可視化為 JSON 並將其可視化為 Text 會顯示不同的內容?
  2. 如何在序列化后獲得正確的值(沒有/ 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM