是否可以在序列化/反序列化期间缩短类型鉴别器属性名称和值?我无权访问类型本身,因此在我的情况下,应该通过配置序列化器本身来完成。我需要将属性名称设置为
"__type"
,将属性值设置为某个自定义名称。
我知道可以在
System.Web.Script.Serialization
JavaScriptTypeResolver
中使用,但我需要在 .NET Core System.Text.Json 中实现。
这是一个如何使用
JavaScriptTypeResolver
完成此操作的示例(该示例基于 这个 MS 示例):
var people = new Person[] { new Person { Name = "AbcPerson" } };
var serialized = new JavaScriptSerializer(new CustomTypeResolver()).Serialize(people);
Console.WriteLine(serialized);
...
public class Person
{
public string Name { get; set; }
}
public class CustomTypeResolver : JavaScriptTypeResolver
{
private readonly IDictionary<string, Type> _typeIds
= new Dictionary<string, Type> { { "P", typeof(Person) } };
public override Type ResolveType(string id)
{
_typeIds.TryGetValue(id, out var result);
return result;
}
public override string ResolveTypeId(Type type)
{
return _typeIds.SingleOrDefault(x => x.Value == type).Key;
}
}
输出为:
[{"__type":"P","姓名":"AbcPerson"}]
编辑:部分解决方案是使用这样的属性
[JsonDerivedType(typeof(Person), typeDiscriminator: "P")]
。但是输出是这样的
[{"$type":"P","姓名":"AbcPerson"}]
我面临着将
$type
更改为 __type
的问题。
要将类型鉴别器属性名称更改为
"__type"
(这是 JavaScriptSerializer
和 DataContractJsonSerializer
使用的鉴别器名称),您需要在要为其发出类型的每个类型上设置 [JsonPolymorphic(TypeDiscriminatorPropertyName = "__type")]
类型鉴别器。例如,如果您的数据模型具有基本类型 Person
和派生类型 Adult
,您需要按如下方式修改它们:
[JsonPolymorphic(TypeDiscriminatorPropertyName = "__type")] // Add this here
[JsonDerivedType(typeof(Person), typeDiscriminator: "P")]
[JsonDerivedType(typeof(Adult), typeDiscriminator: "A")]
public class Person
{
public string Name { get; set; }
}
[JsonPolymorphic(TypeDiscriminatorPropertyName = "__type")] // And also here
[JsonDerivedType(typeof(Adult), typeDiscriminator: "A")]
public class Adult : Person;
演示小提琴#1 这里。
或者,如果您无法轻松修改数据模型,您可以通过 JsonTypeInfo
修饰符
更改鉴别器名称:
public static partial class JsonExtensions
{
public const string MyTypeDiscriminatorPropertyName = "__type";
public static Action<JsonTypeInfo> SetupMyTypeDiscriminatorPropertyName() =>
SetupTypeDiscriminatorPropertyName(MyTypeDiscriminatorPropertyName);
public static Action<JsonTypeInfo> SetupTypeDiscriminatorPropertyName(string name) =>
(JsonTypeInfo typeInfo) =>
{
if (typeInfo.PolymorphismOptions != null)
typeInfo.PolymorphismOptions.TypeDiscriminatorPropertyName = name;
};
}
然后在选项中使用它,例如如下:
var options = new JsonSerializerOptions
{
TypeInfoResolver = new DefaultJsonTypeInfoResolver()
.WithAddedModifier(JsonExtensions.SetupMyTypeDiscriminatorPropertyName()),
// Add other options as required.
};
var json = JsonSerializer.Serialize(people, options);
var people2 = JsonSerializer.Deserialize<Person []>(json, options);
演示小提琴 #2 这里。
另请参阅:
我想你想使用 System.Text.Json 库。 如果您的目标是根据某些自定义规则重命名 json 属性,您可以执行以下操作:
using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;
class CustomType
{
public int Id { get; set; }
public string Name { get; set; }
public InnerCustomType InnerCustomType { get; set; }
}
class InnerCustomType
{
public int Id { get; set; }
public string Name { get; set; }
}
class CustomNamingPolicy : JsonNamingPolicy
{
Dictionary<string, string> propertyRenamingRules = new Dictionary<string, string>()
{
{ "InnerCustomType", "ICT" }
};
public override string ConvertName(string name)
{
// Customize the conversion of class names as needed
string alternativeName;
if(propertyRenamingRules.TryGetValue(name, out alternativeName))
return alternativeName;
return name;
}
}
class Program
{
static void Main()
{
CustomType customObject = new CustomType { Id = 1, Name = "Example", InnerCustomType = new InnerCustomType { Id = 2, Name = "Example 2" } };
JsonSerializerOptions options = new JsonSerializerOptions
{
PropertyNamingPolicy = new CustomNamingPolicy(),
WriteIndented = true
};
// Serialize the object using the custom naming policy
string jsonString = JsonSerializer.Serialize(customObject, options);
Console.WriteLine(jsonString);
}
}
此代码打印此 json:
{
"Id": 1,
"Name": "Example",
"ICT": {
"Id": 2,
"Name": "Example 2"
}
}
我建议您查看此页面以获取有关 CustomNamingPolicy 的更多文档:https://learn.microsoft.com/en-us/dotnet/standard/serialization/system-text-json/customize-properties?pivots =dotnet-8-0