在我正在序列化到文档数据库的对象中,我有一个动态属性,它需要以小写形式写入的所有字符串值以用于索引。我尝试使用自定义转换器,但这需要我编写几种不同类型的序列化代码。我想要的只是标准的序列化行为,但是字符串值被强制为小写。鉴于Newtonsoft库的灵活性,这似乎应该是直截了当的,我还没有找到合适的界面。
请注意,我没有对序列化的直接控制。我写信给Azure COSMOSDB,他们的客户端库使用JSON.Net进行序列化。我可以传入一个自定义序列化器来使用。
更新
以下似乎有效。步骤是:
将对象发送到CosmosDB
private static JToken JTokenStringValuesToLower(JToken startToken)
{
Stack<JEnumerable<JToken>> tokenStack = new Stack<JEnumerable<JToken>>();
tokenStack.Push(startToken.Children());
while (tokenStack.Count != 0)
{
JEnumerable<JToken> children = tokenStack.Pop();
foreach (JToken child in children)
{
if (child.Type == JTokenType.Property)
{
JProperty property = (JProperty)child;
if (child.HasValues)
{
tokenStack.Push(child.Children());
}
if (property.Value.Type == JTokenType.String)
{
property.Value = property.Value.ToString().ToLowerInvariant();
}
}
else if (child.Type == JTokenType.Array && child.HasValues)
{
JArray array = (JArray)child;
JToken[] arrayItems = new JToken[array.Count];
int idx = 0;
bool modified = false;
foreach (JToken arrayItem in array.Children())
{
arrayItems[idx++] = arrayItem;
}
for (int i = 0; i < arrayItems.Length; ++i)
{
JToken token = arrayItems[i];
if (token.Type == JTokenType.String)
{
modified = true;
arrayItems[i] = token.ToString().ToLowerInvariant();
}
}
if (modified)
{
array.Clear();
foreach (JToken item in arrayItems)
{
array.Add(item);
}
}
}
else if (child.HasValues)
{
tokenStack.Push(child.Children());
}
}
}
return startToken;
}