Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用属性定义要使用的JsonConverter_C#_Json.net_Asp.net Core Webapi - Fatal编程技术网

C# 使用属性定义要使用的JsonConverter

C# 使用属性定义要使用的JsonConverter,c#,json.net,asp.net-core-webapi,C#,Json.net,Asp.net Core Webapi,我需要为用特定属性修饰的属性指定一个JsonConverter,在本例中是[DataType(DataType.PostalCode)] 我已经有了一个自定义的JsonConverter,我为它设置了CanConvert方法,如下所示: public override bool CanConvert(Type objectType) => objectType == typeof(string); 当API遇到PostalCode属性时,如何确保使用PostcodeJsonConvert

我需要为用特定属性修饰的属性指定一个
JsonConverter
,在本例中是
[DataType(DataType.PostalCode)]

我已经有了一个自定义的
JsonConverter
,我为它设置了
CanConvert
方法,如下所示:

public override bool CanConvert(Type objectType) => objectType == typeof(string);
当API遇到
PostalCode
属性时,如何确保使用
PostcodeJsonConverter

[DataType(DataType.PostalCode)]
public string Postcode { get; set; }
我尝试了以下方法,但我怀疑
DataType
属性此时不可用

public override bool CanConvert(Type objectType) => 
    objectType == typeof(string) && 
    objectType.GetCustomAttributes(true)
              .OfType<DataTypeAttribute>()
              .Any(dta => dta.DataType == DataType.PostalCode);

您可以将转换器添加到JsonSerializerSettings。因此,与其装饰一切,不如在那里添加邮政编码JSONConverter(取决于使用频率,装饰器可能更好):

对于aspnet核心默认值:

services.AddMvc().AddJsonOptions(o=>o.SerializerSettings.Converters.Add(new PostcodeJsonConverter())

对于JsonConvert:

JsonConvert.SerializeObject(obj, new JsonSerializerSettings
{
    Converters = { new PostcodeJsonConverter() }
});

您可以创建一个自定义的
ContractResolver
,用于查找每个属性上的
数据类型
属性,并将值映射到相应的转换器。以下是您需要的代码:

public class DataTypeResolver : DefaultContractResolver
{
    private Dictionary<DataType, JsonConverter> ConvertersByDataType { get; set; }

    public DataTypeResolver()
    {
        // Adjust this list to match your actual data types and converters
        ConvertersByDataType = new Dictionary<DataType, JsonConverter>
        {
            { DataType.PostalCode, new PostalCodeConverter() },
            { DataType.PhoneNumber, new PhoneNumberConverter() },
        };
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty prop = base.CreateProperty(member, memberSerialization);
        var att = prop.AttributeProvider.GetAttributes(true).OfType<DataTypeAttribute>().FirstOrDefault();
        if (att != null)
        {
            JsonConverter converter;
            if (ConvertersByDataType.TryGetValue(att.DataType, out converter))
            {
                prop.Converter = converter;
            }
        }
        return prop;
    }
}

这是一个有效的演示:

简单地说,是的。要使用自定义JSON转换器,需要将
JsonConverter
属性添加到属性中。JSON.NET无法使用诸如
DataType
之类的属性来猜测您想要哪个转换器。是的,但这不会为所有字符串添加它吗?主要问题不是添加JsonSerializer,而是仅在属性为PostalCode时使用它。您的属性检入
CanConvert
应该可以正常工作。
public class DataTypeResolver : DefaultContractResolver
{
    private Dictionary<DataType, JsonConverter> ConvertersByDataType { get; set; }

    public DataTypeResolver()
    {
        // Adjust this list to match your actual data types and converters
        ConvertersByDataType = new Dictionary<DataType, JsonConverter>
        {
            { DataType.PostalCode, new PostalCodeConverter() },
            { DataType.PhoneNumber, new PhoneNumberConverter() },
        };
    }

    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
    {
        JsonProperty prop = base.CreateProperty(member, memberSerialization);
        var att = prop.AttributeProvider.GetAttributes(true).OfType<DataTypeAttribute>().FirstOrDefault();
        if (att != null)
        {
            JsonConverter converter;
            if (ConvertersByDataType.TryGetValue(att.DataType, out converter))
            {
                prop.Converter = converter;
            }
        }
        return prop;
    }
}
var settings = new JsonSerializerSettings
{
    ContractResolver = new DataTypeResolver()
};
string json = JsonConvert.SerializeObject(yourObject, settings);