C#JsonConverter JSONArray到带分隔符的字符串并返回

C#JsonConverter JSONArray到带分隔符的字符串并返回,c#,arrays,string,json.net,C#,Arrays,String,Json.net,我想实现一个自定义JsonConverter,这样使用 [JsonConverter(typeof(ArrayString))] public string ServiceCodes { get; set; } 其目的是将JSON数组转换为带有分隔符的字符串,例如。, [“this”、“is”、“my”、“json”、“array”]应该变成“this;is;my;json;array”(或任何分隔符)。同样,反过来也是可能的 我很难理解重写JsonConverter的Writ

我想实现一个自定义JsonConverter,这样使用

    [JsonConverter(typeof(ArrayString))]
    public string ServiceCodes { get; set; }
其目的是将JSON数组转换为带有分隔符的字符串,例如。,
[“this”、“is”、“my”、“json”、“array”]
应该变成
“this;is;my;json;array”
(或任何分隔符)。同样,反过来也是可能的

我很难理解重写
JsonConverter
WriteJson
方法

为了提供一些上下文,I
ServiceCodes
是实体上的一个属性(我使用的是EF6)。我认为,与其他一对多实现相比,按照我的要求执行我的案例更容易。然而,我有一个问题,那就是什么时候调用JsonConverter

我只希望
get
在getter需要json时提供json,也就是说,当包含此属性的对象作为json从我的API返回时。例如,我不希望在编写LINQ时调用此转换器

任何帮助都将不胜感激,谢谢

编辑-添加信息

这是课程和一些moc数据

    [ComplexType]
    public class TerminalDuties
    {
        public string TerminalCode { get; set; }

        public string TransportationCode { get; set; }

        [JsonConverter(typeof(ArrayString))]
        public string ServiceCodes { get; set; }
    }
“来源”:{
“终端代码”:“MIA”,
“运输代码”:“GT”,
“ServiceCodes”:[“WH”,“HL”]
}

我尝试了@felix-b的答案,但没有映射。对象为空。我在ArrayString类中有断点,但没有命中。它可能没有尝试映射,因为属性是字符串。解决办法是什么

以下是如何在我的Web API控制器中公开它(继承自ApiController)


使用.NET Framework 4.6.1、ASP.NET Web API 2、Entity Framework 6.1.3、Newtonsoft.Json 10.0.3进行测试。

更新

我的回答最初要求指定
[JsonConverter(typeof(arraysting),';')]
,而不是问题中的
[JsonConverter(typeof(arraysting))]

我向converter类添加了默认构造函数,因此分隔符配置是可选的,如果未指定,将使用分号。现在
[JsonConverter(typeof(arraysting))]
也可以工作

原始答案

转换器仅在通过JSON.NET对实体进行序列化和反序列化期间调用。它不影响从代码中获取或设置属性值,也不影响LINQ查询和DB操作

以下是转换器的实现:

public class ArrayString : JsonConverter
{
    private readonly char _delimiter;

    // UPDATE -- added default constructor, so that 
    // JsonConverter attribute can be specified without the 
    // delimiter parameter, in which case semicolon will be used
    public ArrayString() : this(';')
    {
    }

    public ArrayString(char delimiter)
    {
        _delimiter = delimiter;
    }

    public override bool CanRead => true;
    public override bool CanWrite => true;

    public override bool CanConvert(Type objectType)
    {
        return true; 
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType != JsonToken.StartArray)
        {
            return null;
        }

        var stringValue = new StringBuilder();

        while (reader.Read() && reader.TokenType == JsonToken.String)
        {
            if (stringValue.Length > 0)
            {
                stringValue.Append(_delimiter);
            }
            stringValue.Append((string)reader.Value);
        }

        return stringValue.ToString();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var stringValue = value?.ToString();

        if (stringValue == null)
        {
            writer.WriteNull();
            return;
        }

        var arrayValue = stringValue.Split(_delimiter);

        writer.WriteStartArray();

        foreach (var item in arrayValue)
        {
            writer.WriteValue(item);
        }

        writer.WriteEndArray();
    }
}
以下是如何指定分隔符字符(本例中为分号):


使用.NET Framework 4.6.1、ASP.NET Web API 2、Entity Framework 6.1.3、Newtonsoft.Json 10.0.3进行测试。

更新

我的回答最初要求指定
[JsonConverter(typeof(arraysting),';')]
,而不是问题中的
[JsonConverter(typeof(arraysting))]

我向converter类添加了默认构造函数,因此分隔符配置是可选的,如果未指定,将使用分号。现在
[JsonConverter(typeof(arraysting))]
也可以工作

原始答案

转换器仅在通过JSON.NET对实体进行序列化和反序列化期间调用。它不影响从代码中获取或设置属性值,也不影响LINQ查询和DB操作

以下是转换器的实现:

public class ArrayString : JsonConverter
{
    private readonly char _delimiter;

    // UPDATE -- added default constructor, so that 
    // JsonConverter attribute can be specified without the 
    // delimiter parameter, in which case semicolon will be used
    public ArrayString() : this(';')
    {
    }

    public ArrayString(char delimiter)
    {
        _delimiter = delimiter;
    }

    public override bool CanRead => true;
    public override bool CanWrite => true;

    public override bool CanConvert(Type objectType)
    {
        return true; 
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType != JsonToken.StartArray)
        {
            return null;
        }

        var stringValue = new StringBuilder();

        while (reader.Read() && reader.TokenType == JsonToken.String)
        {
            if (stringValue.Length > 0)
            {
                stringValue.Append(_delimiter);
            }
            stringValue.Append((string)reader.Value);
        }

        return stringValue.ToString();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var stringValue = value?.ToString();

        if (stringValue == null)
        {
            writer.WriteNull();
            return;
        }

        var arrayValue = stringValue.Split(_delimiter);

        writer.WriteStartArray();

        foreach (var item in arrayValue)
        {
            writer.WriteValue(item);
        }

        writer.WriteEndArray();
    }
}
以下是如何指定分隔符字符(本例中为分号):


如果您希望从
“this;is;an;array”
转换为
[“this”、“is”、“an”、“array”]
,您可能需要编写一个自定义转换器来完成此转换(可能只是一个简单的
字符串。拆分
。?)。
JsonConverter
属性仅在使用Json序列化程序转换对象时使用。从了解您使用的web框架开始—ASP.NETMVC、ASP.NETWebAPI等。?然后缩小搜索范围,了解如何序列化API方法的响应。谢谢@GeoffJames!我现在在ASP.NET Web API 2中。是的,我计划使用string.Split和string.Join实现。我只是想用JsonConverter方法来做,别担心。我会一步一步来。将它带回到开始的位置(在属性之前等),首先让它在请求中返回Json。然后,当您确定它工作正常时,就可以开始使用自定义转换器了。否则,您试图一次解决许多问题,并且无法始终确定您刚刚更改的内容的因果关系等[JsonConverter(typeof(ArrayString))]不正确;请改用[JsonConverter(typeof(ArrayString),';')]。由于您在问题中提到了“任意分隔符”,我对其进行了配置。更改了答案,使[JsonConverter(typeof(ArrayString))]现在也可以工作,使用分号作为默认分隔符。如果您希望从
“this;is;an;array”
转换为
[“this”、“is”、“an”、“array”]
,则,您可能需要编写一个自定义转换器来完成此操作(可能只是一个简单的
字符串.Split
。?)。
JsonConverter
属性仅在使用Json序列化程序转换对象时使用。从了解您使用的web框架开始—ASP.NETMVC、ASP.NETWebAPI等。?然后缩小搜索范围,了解如何序列化API方法的响应。谢谢@GeoffJames!我现在在ASP.NET Web API 2中。是的,我计划使用string.Split和string.Join实现。我只是想用JsonConverter方法来做,别担心。我会一步一步来。将它带回到开始的位置(在属性之前等),首先让它在请求中返回Json。然后,当您确定它工作正常时,就可以开始使用自定义转换器了。否则,您会试图一次解决许多问题,并且无法始终确定您刚刚更改的内容的因果关系等。[JsonConver]
[JsonConverter(typeof(ArrayString), ';')]
public string ServiceCodes { get; set; }