使用包含“ /”

时间:2018-10-25 03:04:23

标签: c# json serialization datacontractjsonserializer

我正在使用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+\/..."

您看到了吗?它在每个\之前插入了/,这有很大的不同。

所以我的问题是:

  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字节。因此结果是完全不同的。

那么,如何在不添加\的情况下获得结果?

1 个答案:

答案 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()

提琴:https://dotnetfiddle.net/MQKXSD