如何使用JSON.NET在C#中序列化PSObject?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了如何使用JSON.NET在C#中序列化PSObject?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3836字,纯文字阅读大概需要6分钟。
内容图文
![如何使用JSON.NET在C#中序列化PSObject?](/upload/InfoBanner/zyjiaocheng/822/40cf3be72af9481492d89a21e7b930d1.jpg)
我正在编写一个Cmdlet,需要将对象结构传递给可能包含PSObjects的API客户端.目前,这些序列化作为包含CLIXML的JSON字符串.相反,我需要将它视为一个对象(包括PSObject.Properties中的NoteProperties作为属性,并递归地序列化它们的值).
我尝试编写自己的JsonConverter但由于某种原因它只调用顶级对象,而不是嵌套的PSObjects:
public class PSObjectJsonConverter : JsonConverter {
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) {
if (value is PSObject) {
JObject obj = new JObject();
foreach (var prop in ((PSObject)value).Properties) {
obj.Add(new JProperty(prop.Name, value));
}
obj.WriteTo(writer);
} else {
JToken token = JToken.FromObject(value);
token.WriteTo(writer);
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) {
throw new NotImplementedException();
}
public override bool CanRead {
get { return false; }
}
public override bool CanConvert(Type objectType) {
return true;
}
}
此外,我正在使用CamelCasePropertyNamesContractResolver序列化到驼峰案例.有没有办法让转换器尊重?
解决方法:
以下转换器应正确序列化类型为PSObject的递归嵌套对象:
public class PSObjectJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(PSObject).IsAssignableFrom(objectType);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var psObj = (PSObject)value;
writer.WriteStartObject();
foreach (var prop in psObj.Properties)
{
//Probably we shouldn't try to serialize a property that can't be read.
//https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.pspropertyinfo.isgettable?view=powershellsdk-1.1.0#System_Management_Automation_PSPropertyInfo_IsGettable
if (!prop.IsGettable)
continue;
writer.WritePropertyName(prop.Name);
serializer.Serialize(writer, prop.Value);
}
writer.WriteEndObject();
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanRead { get { return false; } }
}
笔记:
>在WriteJson中,将传入的对象值序列化为每个属性的值.当然你的意思是prop.Value.
>当传入的对象类型是PSObject类型时,仅从CanConvert()返回true,可以避免在WriteJson()中为非PSObject类型实现默认序列化.
>当您调用JToken.FromObject(value)时,您没有使用传入的JsonSerializer序列化程序.因此,任何JsonSerializerSettings(包括转换器)都将丢失.从理论上讲,您可以使用JToken.FromObject(Object, JsonSerializer)来保留设置,但如果您这样做,则会遇到JSON.Net throws StackOverflowException when using [JsonConvert()]中描述的错误.幸运的是,由于我们现在在需要默认序列化时从CanConvert返回false,因此不再需要.
>无需构造中间JObject.您可以直接写入JsonWriter,这将更有效.
更新:此外,我正在使用CamelCasePropertyNamesContractResolver序列化到驼峰案例.有没有办法让转换器尊重?
为类型引入custom JsonConverter后,您需要手动完成所有操作,包括重新映射属性名称.这是WriteJson()的一个版本,使用DefaultContractResolver.NamingStrategy来处理这个问题:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var psObj = (PSObject)value;
writer.WriteStartObject();
var resolver = serializer.ContractResolver as DefaultContractResolver;
var strategy = (resolver == null ? null : resolver.NamingStrategy) ?? new DefaultNamingStrategy();
foreach (var prop in psObj.Properties)
{
//Probably we shouldn't try to serialize a property that can't be read.
//https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.pspropertyinfo.isgettable?view=powershellsdk-1.1.0#System_Management_Automation_PSPropertyInfo_IsGettable
if (!prop.IsGettable)
continue;
writer.WritePropertyName(strategy.GetPropertyName(prop.Name, false));
serializer.Serialize(writer, prop.Value);
}
writer.WriteEndObject();
}
请注意,命名策略是在Json.NET 9.0.1中引入的,因此如果您使用的是早期版本,则需要创建自己的驼峰案例名称映射器,如this answer中所示.
内容总结
以上是互联网集市为您收集整理的如何使用JSON.NET在C#中序列化PSObject?全部内容,希望文章能够帮你解决如何使用JSON.NET在C#中序列化PSObject?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。