- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须向 Web REST 服务发送和接收 JSON 对象。这些对象由 DLL 生成,该 DLL 将属性名称序列化为大驼峰式命名法(“PropertyName”),而 Web 服务需要蛇形命名法(“property_name”)。另外,DLL 将数值序列化为 float ,但 REST API 需要所有字符串。处理对象后,REST 服务返回蛇形 JSON。
JSON 很复杂,包含嵌套数组和对象。从 REST 字符串转换回来时,我可以跳过数字字符串的去字符串化,但我仍然必须将属性名称重新转换为大驼峰式大小写。
我正在考虑使用 Newtonsoft Json 库编写一个帮助器类,但它看起来比我预期的要棘手。转换器应接受 JSON 并返回 JSON。
示例:
{
"FirstObject": {
"NestedObject": {
"AttributeString": "ok",
"AttributeNumeric": 123.45
},
"OtherObject": [{
"ArrayVal": 100
}, {
"ArrayVal": 200
}]
}
}
应该变成
{
"first_object": {
"nested_object": {
"attribute_string": "ok",
"attribute_numeric": "123.45"
},
"other_object": [{
"array_val": "100"
}, {
"array_val": "200"
}]
}
}
我看到 Json.Net 库有 SnakeCaseNamingStrategy
和 CamelCaseNamingStrategy
类,因此我们的想法是使用 JsonTextReader
来解析输入,更改属性名称的命名约定,将数值设置为字符串,并使用 JsonTextWriter
写入修改后的标记。
我找不到任何有关如何执行此操作的示例。
最佳答案
实现您想要的操作的最简单方法是使用一组与您的 JSON 匹配的模型类。 (您可以通过将 JSON 的完整示例复制到剪贴板,然后使用 Edit -> Paste Special -> Paste JSON as Classes
功能在 Visual Studio 中生成类。)使模型类使用属性名称采用大驼峰式命名(无论如何,这是 C# 的标准命名约定),并使用字符串代替数字属性。
因此,对于您的示例 JSON,模型类将如下所示:
public class RootObject
{
public FirstObject FirstObject { get; set; }
}
public class FirstObject
{
public NestedObject NestedObject { get; set; }
public List<OtherObject> OtherObject { get; set; }
}
public class NestedObject
{
public string AttributeString { get; set; }
public string AttributeNumeric { get; set; }
}
public class OtherObject
{
public string ArrayVal { get; set; } // using string instead of int here
}
然后,要将大驼峰式 JSON 转换为蛇形式,您可以执行以下操作:
var obj = JsonConvert.DeserializeObject<RootObject>(json);
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new SnakeCaseNamingStrategy { ProcessDictionaryKeys = true }
},
Formatting = Formatting.Indented
};
json = JsonConvert.SerializeObject(obj, settings);
原始 JSON 会自然地反序列化为模型,因为属性名称已经匹配。 Json.Net 会根据需要自动将 JSON 中的数值转换为字符串以适合类属性。在序列化时,SnakeCaseNamingStrategy
发挥作用,将属性名称更改为蛇形命名法。数值以字符串形式写出,因为这是在类中声明属性的方式。
要以另一种方式返回,您可以这样做:
obj = JsonConvert.DeserializeObject<RootObject>(json, settings); // same settings as above
json = JsonConvert.SerializeObject(obj, Formatting.Indented);
这里,在反序列化期间,Json.Net 使用 SnakeCaseNamingStrategy
将模型属性名称再次转换为蛇形大小写,以将它们与 JSON 属性匹配。数值已经是 JSON 中的字符串,因此不需要转换。在序列化时,我们没有使用任何特殊设置,因此属性名称完全按照声明的方式写出,即大驼峰式大小写。保存数值的字符串属性仍然是字符串(您说这在您的问题中没问题)。
这是一个往返演示:https://dotnetfiddle.net/3Pb1fT
<小时/>如果您没有可用的模型,仍然可以使用您建议的 JsonReader
/JsonWriter
方法进行此转换,但这需要花费一些时间只需多一点代码即可将它们粘合在一起并进行转换。这是一个辅助方法,可以完成大部分繁重的工作:
public static void ConvertJson(TextReader textReader, TextWriter textWriter,
NamingStrategy strategy,
Formatting formatting = Formatting.Indented)
{
using (JsonReader reader = new JsonTextReader(textReader))
using (JsonWriter writer = new JsonTextWriter(textWriter))
{
writer.Formatting = formatting;
if (reader.TokenType == JsonToken.None)
{
reader.Read();
ConvertJsonValue(reader, writer, strategy);
}
}
}
private static void ConvertJsonValue(JsonReader reader, JsonWriter writer,
NamingStrategy strategy)
{
if (reader.TokenType == JsonToken.StartObject)
{
writer.WriteStartObject();
while (reader.Read() && reader.TokenType != JsonToken.EndObject)
{
string name = strategy.GetPropertyName((string)reader.Value, false);
writer.WritePropertyName(name);
reader.Read();
ConvertJsonValue(reader, writer, strategy);
}
writer.WriteEndObject();
}
else if (reader.TokenType == JsonToken.StartArray)
{
writer.WriteStartArray();
while (reader.Read() && reader.TokenType != JsonToken.EndArray)
{
ConvertJsonValue(reader, writer, strategy);
}
writer.WriteEndArray();
}
else if (reader.TokenType == JsonToken.Integer)
{
// convert integer values to string
writer.WriteValue(Convert.ToString((long)reader.Value));
}
else if (reader.TokenType == JsonToken.Float)
{
// convert floating point values to string
writer.WriteValue(Convert.ToString((double)reader.Value,
System.Globalization.CultureInfo.InvariantCulture));
}
else // string, bool, date, etc.
{
writer.WriteValue(reader.Value);
}
}
要使用它,您只需为输入 JSON 设置一个 TextReader
并为输出设置一个 TextWriter
,并传入适当的 NamingStrategy
您想要用于转换的。例如,要将原始 JSON 字符串转换为蛇形大小写,您可以这样做:
using (StringReader sr = new StringReader(upperCamelCaseJson))
using (StringWriter sw = new StringWriter())
{
ConvertJson(sr, sw, new SnakeCaseNamingStrategy(), formatting);
string snakeCaseJson = sw.ToString();
...
}
或者,如果 JSON 的源和/或目标是某种类型的流,则可以使用 StreamReader
/StreamWriter
代替:
using (StreamReader sr = new StreamReader(inputStream))
using (StreamWriter sw = new StreamWriter(outputStream))
{
ConvertJson(sr, sw, new SnakeCaseNamingStrategy(), formatting);
}
现在,回程时遇到了一些问题。 NamingStrategy
仅在一个方向上起作用;它不提供反转转换的工具。这意味着 Newtonsoft 提供的 NamingStrategy
类都无法按照您想要的方式将蛇形大小写转换回大驼峰大小写。 CamelCaseNamingStrategy
将不起作用,因为它不希望以蛇形命名法开头(它需要大驼峰式命名),并且它的输出无论如何都不是大驼峰式。 DefaultNamingStrategy
也不起作用,因为它实际上根本不执行任何转换 - 它只是一个传递。
解决方案是创建您自己的自定义 NamingStrategy
。幸运的是,这并不难做到。只需从基 NamingStrategy
类派生并实现抽象 ResolvePropertyName
方法即可:
// This naming strategy converts snake case names to upper camel case (a.k.a. proper case)
public class ProperCaseFromSnakeCaseNamingStrategy : NamingStrategy
{
protected override string ResolvePropertyName(string name)
{
StringBuilder sb = new StringBuilder(name.Length);
for (int i = 0; i < name.Length; i++)
{
char c = name[i];
if (i == 0 || name[i - 1] == '_')
c = char.ToUpper(c);
if (c != '_')
sb.Append(c);
}
return sb.ToString();
}
}
现在,您可以如上所述将这个新策略传递给 ConvertJson
方法,将蛇形 JSON 转换回大驼峰式命名。
关于c# - 将 JSON 驼峰式大小写转换为蛇形大小写(反之亦然)并将数值字符串化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53779796/
我正在尝试将一个字符串逐个字符地复制到另一个字符串中。目的不是复制整个字符串,而是复制其中的一部分(我稍后会为此做一些条件......) 但我不知道如何使用迭代器。 你能帮帮我吗? std::stri
我想将 void 指针转换为结构引用。 结构的最小示例: #include "Interface.h" class Foo { public: Foo() : mAddress((uint
这有点烦人:我有一个 div,它从窗口的左上角开始过渡,即使它位于文档的其他任何位置。我试过 usign -webkit-transform-origin 但没有成功,也许我用错了。有人可以帮助我吗?
假设,如果将 CSS3 转换/转换/动画分配给 DOM 元素,我是否可以检测到该过程的状态? 我想这样做的原因是因为我正在寻找类似过渡链的东西,例如,在前一个过渡之后运行一个过渡。 最佳答案 我在 h
最近我遇到了“不稳定”屏幕,这很可能是由 CSS 转换引起的。事实上,它只发生在 Chrome 浏览器 上(可能还有 Safari,因为一些人也报告了它)。知道如何让它看起来光滑吗?此外,您可能会注意
我正在开发一个简单的 slider ,它使用 CSS 过渡来为幻灯片设置动画。我用一些基本样式和一些 javascript 创建了一支笔 here .注意:由于 Codepen 使用 Prefixfr
我正在使用以下代码返回 IList: public IList FindCodesByCountry(string country) { var query =
如何设计像这样的操作: 计算 转化 翻译 例如:从“EUR”转换为“CNY”金额“100”。 这是 /convert?from=EUR&to=CNY&amount=100 RESTful 吗? 最佳答
我使用 jquery 组合了一个图像滚动器,如下所示 function rotateImages(whichHolder, start) { var images = $('#' +which
如何使用 CSS (-moz-transform) 更改一个如下所示的 div: 最佳答案 你可以看看Mozilla Developer Center .甚至还有例子。 但是,在我看来,您的具体示例不
我需要帮助我正在尝试在选中和未选中的汉堡菜单上实现动画。我能够为菜单设置动画,但我不知道如何在转换为 0 时为左菜单动画设置动画 &__menu { transform: translateX(
我正在为字典格式之间的转换而苦苦挣扎:我正在尝试将下面的项目数组转换为下面的结果数组。本质上是通过在项目第一个元素中查找重复项,然后仅在第一个参数不同时才将文件添加到结果集中。 var items:[
如果我有两个定义相同的结构,那么在它们之间进行转换的最佳方式是什么? struct A { int i; float f; }; struct B { int i; float f; }; void
我编写了一个 javascript 代码,可以将视口(viewport)从一个链接滑动到另一个链接。基本上一切正常,你怎么能在那里看到http://jsfiddle.net/DruwJ/8/ 我现在的
我需要将文件上传到 meteor ,对其进行一些图像处理(必要时进行图像转换,从图像生成缩略图),然后将其存储在外部图像存储服务器(s3)中。这应该尽可能快。 您对 nodejs 图像处理库有什么建议
刚开始接触KDB+,有一些问题很难从Q for Mortals中得到。 说,这里 http://code.kx.com/wiki/JB:QforMortals2/casting_and_enumera
我在这里的一个项目中使用 JSF 1.2 和 IceFaces 1.8。 我有一个页面,它基本上是一大堆浮点数字段的大编辑网格。这是通过 inputText 实现的页面上的字段指向具有原始值的值对象
ScnMatrix4 是一个 4x4 矩阵。我的问题是什么矩阵行对应于位置(ScnVector3),旋转(ScnVector4),比例(ScnVector3)。第 4 行是空的吗? 编辑: 我玩弄了
恐怕我是 Scala 新手: 我正在尝试根据一些简单的逻辑将 Map 转换为新 Map: val postVals = Map("test" -> "testing1", "test2" -> "te
输入: This is sample 1 This is sample 2 输出: ~COLOR~[Green]This is sample 1~COLOR~[Red]This is sam
我是一名优秀的程序员,十分优秀!