将Boolean JValue转换为可分析布尔字符串
我有一个Web服务正在解析JSON请求并使用值来设置XML文档的属性。将Boolean JValue转换为可分析布尔字符串
例如,以下请求
{ name: "Foo", isEnabled: true, size: 100 }
应该更新XML文档此,
<SomeElement name="Foo" isEnabled="true" size="100" />
,而是它会产生这样的:
<SomeElement name="Foo" isEnabled="True" size="100" />
我没有用于JSON输入或我正在修改的XML的结构化类型(我是这里的中间人),所以我解析了JSON到JObject
,XML是原始的XmlDocument
。
问题是,当我浏览JObject
时,我得到每个属性JValue,并通过调用JValue.ToString()
将其转换为字符串以放入XML属性。对于整数和字符串值,这工作得很好,但是布尔值,JValue.ToString()
导致True/False
,而不是true/false
所以当XML文档的用户试图将XML文档解析为他们的对象,它失败,因为True
是无效的布尔值。另一方面,如果我使用JsonConvert.SerializeObject()
来转换值,那么布尔值和整数值将工作,但字符串值将被引用(按照JSON的要求)。
有没有更好的方式来获得正确的弦值,我需要,还是我只是需要特殊的情况下布尔JValue
在我的转换代码?
逻辑您需要的是XmlNodeConverter.ConvertTokenToXmlValue()
,根据JSON令牌类型调用正确的XmlConvert.ToString()
重载。不幸的是,这不是公开的。访问此方法最简单的方法(而不是复制它的逻辑我想)是创建一个临时JObject
包含您JValue
,它XmlNodeConverter
转换为XElement
,然后返回创建XElement
的价值:
public static class JsonExtensions
{
public static string ToXmlValue(this JValue value)
{
if (value == null)
return null;
var obj = new JObject(new JProperty("a", value.DeepClone())); // XmlNodeConverter only works deserializing an object, so make a synthetic object.
return obj.ToXElement().Value;
}
public static XElement ToXElement(this JObject obj)
{
if (obj == null)
return null;
using (var reader = obj.CreateReader())
return JsonExtensions.DeserializeXElement(reader);
}
public static XElement DeserializeXElement(JsonReader reader)
{
return DeserializeXElement(reader, null, false);
}
public static XElement DeserializeXElement(JsonReader reader, string deserializeRootElementName, bool writeArrayAttribute)
{
var converter = new Newtonsoft.Json.Converters.XmlNodeConverter() { DeserializeRootElementName = deserializeRootElementName, WriteArrayAttribute = writeArrayAttribute };
var jsonSerializer = JsonSerializer.CreateDefault(new JsonSerializerSettings { Converters = new JsonConverter[] { converter } });
return jsonSerializer.Deserialize<XElement>(reader);
}
}
这应该正确处理所有向XML的值类型转换 - DateTime
,bool
,decimal
等 - 具有正确的国际化。
你也可能想看看Converting between JSON and XML,看看Json.NET内置的转换API可以帮助你。
您可以为JValue
,让结果创建一个扩展方法,你想:
public static class JsonExtensions
{
public static string ToXmlFriendlyString(this JValue jv)
{
return (jv.Type == JTokenType.Boolean ? jv.ToString().ToLower() : jv.ToString());
}
}
然后,无论你在呼唤JValue.ToString()
调用扩展方法来代替,例如:
JValue jv = new JValue(true);
Console.WriteLine(jv.ToXmlFriendlyString());
可能是最有效的选择,但我希望避免特殊情况下的各种类型。 –
是的,不幸的是,我不能仅仅使用内置的Json.NET转换,因为它们在丢失订单信息时使用了一些问题。我选择这个作为正确的答案,因为它会返回可用类型的“正确的”序列化值。希望它最终不会太昂贵。 –