JSON序列化为字典特殊字符转义处理NET 5.0 CORE

อาเหว่ย 2020-12-20 01:06:17
JSON原始数据:
--------------------------------------
{
"aa":
{"a1":"aa11",
"a2":"https:\/\/www.abc.com\/asfasd8asfad"
},
"bb":"bbbbbbbbbasdfasdxxx"}
--------------------------------------
如果JAVA用字典的话可以得到两个键值。aa和bb;aa转为字符串值和JSON原来一样。
是这个:
{"a1":"aa11",
"a2":"https:\/\/www.abc.com\/asfasd8asfad"
}
----------------
但我使用同样的方式C#语言得到的键值aa和bb,bb是一样的字符串。这个不用讲了。
但aa的值 是这个:
{"a1":"aa11",
"a2":"https://www.abc.com/asfasd8asfad"
}
--------------------------------------------
想知道如何得到原始的数据,使用字典。不转义。因为我不知道里面是不是只有这个字符转义了。所以必须要知道解决方法。
我的C#代码如下:
Dictionary<string, object> dicData= JsonSerializer.Deserialize<Dictionary<string, object>>(strData);//将JSON转为字典
因为在这句的时候已经把数据转掉了。后面无法转回来。
我就算加了参数也不行
JsonSerializerOptions jso = new JsonSerializerOptions()
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,//解决中文乱码-不转义Unicode数据
IgnoreNullValues = true,//去空值
};
这个加上也不行。

其实就是一句话,把对象JSON转为字符时不要转义;【提醒是JSON对象不是字符串aa】
我要得到数据"https:\/\/www.abc.com\/asfasd8asfad"
不是得到数据"https://www.abc.com/asfasd8asfad"


...全文
6100 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 33 楼 dugupiaoyun 的回复:
使用DataContractJsonSerializer,如果用Newtonsoft.Json会使JAVA那边收到的解码乱码。
这个只有MS的那个才可以有效对接
dugupiaoyun 2020-12-25
  • 打赏
  • 举报
回复
使用DataContractJsonSerializer,如果用Newtonsoft.Json会使JAVA那边收到的解码乱码。
八爻老骥 2020-12-24
  • 打赏
  • 举报
回复
引用 27 楼 fly4free 的回复:
to 楼主,
有一点我一开始就错了, '\/' 字符是合法的 json 转义字符序列

而你要把 合法的原始字符序列(包括转义字符序列) 提取出来,这事儿我理解了,无非就是解析库几行代码的事儿(我原以为 '/' 不用转义所以直觉上认为多加的是多余的非法字符)

只不过我没有VS2019,一切都是我参照手头的 VS2017 下运行结果而说的


你去看一下他的for循环是怎么写的就明白,为什么会有问题了。
江湖评谈 2020-12-24
  • 打赏
  • 举报
回复
fly4free 2020-12-24
  • 打赏
  • 举报
回复
to 楼主,
有一点我一开始就错了, '\/' 字符是合法的 json 转义字符序列

而你要把 合法的原始字符序列(包括转义字符序列) 提取出来,这事儿我理解了,无非就是解析库几行代码的事儿(我原以为 '/' 不用转义所以直觉上认为多加的是多余的非法字符)

只不过我没有VS2019,一切都是我参照手头的 VS2017 下运行结果而说的
八爻老骥 2020-12-24
  • 打赏
  • 举报
回复
引用 29 楼 fly4free 的回复:
[quote=引用 28 楼 icoolno1 的回复:]

你去看一下他的for循环是怎么写的就明白,为什么会有问题了。


我的用VS2017,用的是 .NET 4.6.3 引用 Newtonsoft.Json 12.0.3 的 dll
用的是你25 楼的代码,不过版本低的缘故吧,只能用下面代码替代

string str1 = "{\"aa\":{\"a1\":\"aa11\",\"a2\":\"https:\\/\\/www.abc.com\\/asfasd8asfad\"},\"bb\":\"bbbbbbbbbasdfasdxxx\"}";
JsonReader reader = new JsonTextReader(new StringReader(str1));
Dictionary<string, object> dicData2 = JsonSerializer.CreateDefault().Deserialize<Dictionary<string, object>>(reader);
foreach (var key2 in dicData2.Keys)
{
var obj = dicData2[key2];
Console.WriteLine(key2 + ":" + dicData2[key2]);
}

输出是

aa:{
"a1": "aa11",
"a2": "https://www.abc.com/asfasd8asfad"
}
bb:bbbbbbbbbasdfasdxxx


而不是你图中所示的内容

这就表示新旧版本兼容性不好,或者 我用的库 和 .NET CORE 5.0 集成的库 的实现不一致。

这样理解json,有点兼容性问题。
除非所有系统都更新了,不然像我一样用低版本的项目就无法解析之前生成的JSON了
我仍然挺好奇,楼主那个 JSON原始数据 到底怎么生成的,我 22 楼的代码,明显显示出我的疑问。[/quote]

明显,.net 5.0里aa对应的就是个字符串,转义也是针对C#字符串的,你这个跟楼主的问题一样,当成json对象来处理了,对aa的内容进行了二次解析,只不过楼主在For循环里自己写的,你这个应该是newdonjson自动去做了。
fly4free 2020-12-24
  • 打赏
  • 举报
回复
打错了
控制台程序用的是 .NET 4.6.2


fly4free 2020-12-24
  • 打赏
  • 举报
回复
引用 28 楼 icoolno1 的回复:
你去看一下他的for循环是怎么写的就明白,为什么会有问题了。


我的用VS2017,用的是 .NET 4.6.3 引用 Newtonsoft.Json 12.0.3 的 dll
用的是你25 楼的代码,不过版本低的缘故吧,只能用下面代码替代

string str1 = "{\"aa\":{\"a1\":\"aa11\",\"a2\":\"https:\\/\\/www.abc.com\\/asfasd8asfad\"},\"bb\":\"bbbbbbbbbasdfasdxxx\"}";
JsonReader reader = new JsonTextReader(new StringReader(str1));
Dictionary<string, object> dicData2 = JsonSerializer.CreateDefault().Deserialize<Dictionary<string, object>>(reader);
foreach (var key2 in dicData2.Keys)
{
var obj = dicData2[key2];
Console.WriteLine(key2 + ":" + dicData2[key2]);
}

输出是

aa:{
"a1": "aa11",
"a2": "https://www.abc.com/asfasd8asfad"
}
bb:bbbbbbbbbasdfasdxxx


而不是你图中所示的内容

这就表示新旧版本兼容性不好,或者 我用的库 和 .NET CORE 5.0 集成的库 的实现不一致。

这样理解json,有点兼容性问题。
除非所有系统都更新了,不然像我一样用低版本的项目就无法解析之前生成的JSON了
我仍然挺好奇,楼主那个 JSON原始数据 到底怎么生成的,我 22 楼的代码,明显显示出我的疑问。
八爻老骥 2020-12-23
  • 打赏
  • 举报
回复
程序写得有问题,正确写法:
注意:Console.WriteLine(key + ":" + dicData[key]);

string str1 = "{\"aa\":{\"a1\":\"aa11\",\"a2\":\"https:\\/\\/www.abc.com\\/asfasd8asfad\"},\"bb\":\"bbbbbbbbbasdfasdxxx\"}";
Dictionary<string, object> dicData = JsonSerializer.Deserialize<Dictionary<string, object>>(str1);
foreach (var key in dicData.Keys)
{
Console.WriteLine(key + ":" + dicData[key]);
}


fly4free 2020-12-23
  • 打赏
  • 举报
回复
你没明白,我几层楼都说的是你的【JSON原始数据】有问题,那就不叫一个【合格的json字符串】(各种验证网站都说合法,我也不能说非法,只能说不合格),我就纳闷,它咋不异常呢?

你网上搜几个 json 验证的在线工具,那种可以 把你输入的 json串,转成 对象的
我先给你一个:
https://www.bejson.com/explore/index_new/
你看看结果是不是全都是 C# 代码解析的结果


你拿到的 json 到底时谁生成的?不会是手工拼接的吧?
我之前和Java服务器端合作过 json 相关东西,他用的时候就是 key:value 对,然后把叶子 value 都当成 String,所以直接提取String,而缺少"反转义"过程,我认为你这个问题肯恶搞就是这样的,就是生成的时候没有<转义表达化>。

那这就不对了,json字符串,每一个 value 都要符合一定的标准,该 <转义表达化>的都要<转义表达化>,你这个json字符串的格式有点问题,这就是 c#json库解析的结果与 Java 词典方式的解析结果不一致的原因

因为我22楼用库生成的代码的结果就与你的【JSON原始数据】不一致,你的是不正常转义使用,在【json解析】(不是String提取哦)过程,就把不正常的转义字符给咔嚓了(我前几个回帖之前,我以为会抛异常呢)

还有我想起你说的,你用了 JsonSerializerOptions 也不好使。其实我昨晚就发现了,你的注释不是说明了吗,那只是对应中文的转义啊,和你原本想要的【不转义】没关系啊。如果真有你所想象的【不转义】,我还不理解呢……。
谁来说说,我长长知识。
  • 打赏
  • 举报
回复
现在我都用的NET5的原生库。没有用三方的。这种特殊字符只有换掉使用的时候再换过来就好了。 不太好看,但很保险。你讲的有一点我不赞同。转义是一个方法不能修改我的原始数据。所以不能多次转义。 至于我要不要是用户的事情。不然用了你的方法。所有转义符都变不见了。那怎么使用呢正确的数据呢。 个人见解,不喜不喷,感谢你用心回复。
引用 22 楼 fly4free 的回复:
很久没用 这个库了,你用的可能是新版本,我没有 JsonSerializerOptions 下述代码,在用的 Newtonsoft.Json.dll .NET 4.0 版本下成功

JObject root = new JObject();
root["a1"] = "aa11";
root["a2"] = "http:\\/\\/www\\";  // 这条赋值必须转义,否则编译不了
String str2 = root.ToString();
str2的值是:

{
  "a1": "aa11",
  "a2": "http:\\/\\/www\\"
}
root["a2"]的值是:http:\/\/www\ 却是如你3楼所说,两次转义解析,但是我觉得这很正常啊。这样才是稳定。 原始数据必须带足转义字符,包括次数和层级
fly4free 2020-12-22
  • 打赏
  • 举报
回复
好神奇的需求。

你这需求,我一打眼,觉得相当于 parse 一个 String 然后,把里面须要转义的字符串都还原展开。。。。
比如,原来'\\'替换成'\' ,现在反其道而行,把'\'转换成 '\\'
因为你这个是 json 解析,所以,【肯定会有转义】,否则json解析会失败

其实我很好奇,'\/' 这是个合法转义吗?真神奇 (因为按我上述思路,这个'/'不用转义,所以达不到你的需求……)
fly4free 2020-12-22
  • 打赏
  • 举报
回复
很久没用 这个库了,你用的可能是新版本,我没有 JsonSerializerOptions
下述代码,在用的 Newtonsoft.Json.dll .NET 4.0 版本下成功


JObject root = new JObject();
root["a1"] = "aa11";
root["a2"] = "http:\\/\\/www\\"; // 这条赋值必须转义,否则编译不了
String str2 = root.ToString();


str2的值是:

{
"a1": "aa11",
"a2": "http:\\/\\/www\\"
}


root["a2"]的值是:http:\/\/www\

却是如你3楼所说,两次转义解析,但是我觉得这很正常啊。这样才是稳定。

原始数据必须带足转义字符,包括次数和层级
  • 打赏
  • 举报
回复
再提醒一下。无论那个序列化的引用都一样 原生和三方的结果 都一样
  • 打赏
  • 举报
回复
引用 17 楼 fly4free 的回复:
[quote=引用 16 楼 Let's GO GO GO 的回复:] 楼主并没有'\/'这样的东西。你要认真看代码内容。和打印内容。这个区别好大的。
对于下行代码,ide 会有提示不是合法的转义: var strData = "{\"a\":\"https:\/\/www.abc.com\"}"; 那么可以推出: "a2":"https:\/\/www.abc.com\/asfasd8asfad" 本身里面的东西就不是合法的【转义字符使用】, 楼主在用java的【使用字典】方法解析过程中,其Java实现应该是属于【不严格】的解析, 而用c#(看楼主的意思也是用字典方式),但我猜C#实现可能是严格的,解析过程中直接把转义字符给干掉了 另外,我觉得,下行的输入 "a2":"https:\\/\\/www.abc.com\\/asfasd8asfad" 才能得到 https:\/\/www.abc.com\/asfasd8asfad 这样的结果。 但是从人类可阅读的理解程度上分析,输入的格式可能不满足某种业务意义: 一个错误格式的输入,也许异常处理的时候,想要展示其原因,所以要保持原样输出吧? 如果是这样,我就不奇怪了。 如果是这样,直接把整个json字符串打印出来就得了。 如果是这样,我觉得这个json串的生成乃是手工拼的,如果用库生成,一定是合法的【转义字符使用】,也就是【"a2":"https:\\/\\/www.abc.com\\/asfasd8asfad"】这样 [/quote] 你可能没太明白。只有看上面代码才行。因为\\和\是同一个东西。一个是代码中。一个是打印出来的。 反复测试了。确实执行了两次
fly4free 2020-12-22
  • 打赏
  • 举报
回复
说白了,我认为

楼主提供的 JSON原始数据的样例,本身就不是一个规范的 JSON 字符序串。
如果出现什么不对劲,可能也是层实现的问题。

正确的解决方法,是把 JSON原始数据,纠正过来,使其规范
fly4free 2020-12-22
  • 打赏
  • 举报
回复
引用 16 楼 Let's GO GO GO 的回复:
楼主并没有'\/'这样的东西。你要认真看代码内容。和打印内容。这个区别好大的。


对于下行代码,ide 会有提示不是合法的转义:
var strData = "{\"a\":\"https:\/\/www.abc.com\"}";

那么可以推出:
"a2":"https:\/\/www.abc.com\/asfasd8asfad"
本身里面的东西就不是合法的【转义字符使用】,

楼主在用java的【使用字典】方法解析过程中,其Java实现应该是属于【不严格】的解析,
而用c#(看楼主的意思也是用字典方式),但我猜C#实现可能是严格的,解析过程中直接把转义字符给干掉了

另外,我觉得,下行的输入
"a2":"https:\\/\\/www.abc.com\\/asfasd8asfad"
才能得到
https:\/\/www.abc.com\/asfasd8asfad
这样的结果。

但是从人类可阅读的理解程度上分析,输入的格式可能不满足某种业务意义:
一个错误格式的输入,也许异常处理的时候,想要展示其原因,所以要保持原样输出吧?

如果是这样,我就不奇怪了。
如果是这样,直接把整个json字符串打印出来就得了。
如果是这样,我觉得这个json串的生成乃是手工拼的,如果用库生成,一定是合法的【转义字符使用】,也就是【"a2":"https:\\/\\/www.abc.com\\/asfasd8asfad"】这样
Let's GO GO GO 2020-12-22
  • 打赏
  • 举报
回复
引用 15 楼 fly4free 的回复:
好神奇的需求。 你这需求,我一打眼,觉得相当于 parse 一个 String 然后,把里面须要转义的字符串都还原展开。。。。 比如,原来'\\'替换成'\' ,现在反其道而行,把'\'转换成 '\\' 因为你这个是 json 解析,所以,【肯定会有转义】,否则json解析会失败 其实我很好奇,'\/' 这是个合法转义吗?真神奇 (因为按我上述思路,这个'/'不用转义,所以达不到你的需求……)
你可能没太注意楼主的需求。简单一句话就是 json里面的内容有右杠的经过序列化会少一层,就是多转义了一次。 我测试了确实是这样。 代码数据是 \\ 实际数据是\ ;\/只是内容需要这个而乙。和左杠无关的。 楼主并没有'\/'这样的东西。你要认真看代码内容。和打印内容。这个区别好大的。
Let's GO GO GO 2020-12-21
  • 打赏
  • 举报
回复
引用 6 楼 enaking 的回复:
vs就是会转义的,建议你百度一下vs转义规则。用@"text"来表达。
大神,楼主的问题还是无人能解。都是讲道理。哈哈。
enaking 2020-12-21
  • 打赏
  • 举报
回复
vs就是会转义的,建议你百度一下vs转义规则。用@"text"来表达。
加载更多回复(12)

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧