Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse Json to return string or string array?

Tags:

json

c#

json.net

Can I make these code to one method with generics?

I want return string or string array because my Json file is like below.

Json sample

So I want to do like this.

public static string langFilePath = @"..\..\..\Core\Data\Lang.json";
public static JObject lang = JObject.Parse(File.ReadAllText(langFilePath));

public static string[] GetJsonValue(string key)
{
    string[] values = lang[key].ToObject<string[]>();

    return values;
}

But value of key can not be string array.

It can also be string.

like image 561
Busted Avatar asked Feb 17 '26 21:02

Busted


1 Answers

Rather than returning one of two possible return types, it's probably simpler to just coerce a single string to an array containing that string. Assuming you don't control the Json, you probably want to write a custom JsonConverter. Here's my quick and dirty stab at the problem:

public class LangEntryConverter: JsonConverter<string[]>
{
    // WriteJson implementation only needed if you need to serialize a value back to Json
    public override void WriteJson(JsonWriter writer, string[] value, JsonSerializer serializer)
    {
        if (value.Length == 1)
        {
            writer.WriteValue(value[0]);
        }
        else
        {
            writer.WriteStartArray();
            for (var i = 0; i < value.Length; i++)
            {
                writer.WriteValue(value[i]);
            }
            writer.WriteEndArray();
        }
    }

    public override string[] ReadJson(JsonReader reader, Type objectType, string[] existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var values = new List<string>();
        if (reader.TokenType == JsonToken.StartArray)
        {
            while (reader.Read() && reader.TokenType != JsonToken.EndArray)
            {
                if (reader.TokenType == JsonToken.String)
                {
                    values.Add((string)reader.Value);
                }
                else
                {
                    throw new Exception($"Unexpected token type: {reader.TokenType}");
                }
            }
        }
        else if (reader.TokenType == JsonToken.String)
        {
            values.Add((string)reader.Value);
        }

        return values.ToArray();
    }
}

And then call it like so:

// Note: double-quotations are required for C#'s verbatim string syntax; they are not part of the Json
var json = @"{
  ""foo"": ""one"",
  ""bar"": [""one"", ""two"", ""three""]
}";

var lang = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(json, new LangEntryConverter());
Console.WriteLine(String.Join(", ", lang["foo"]));  // one
Console.WriteLine(String.Join(", ", lang["bar"]));  // one, two, three

Of course, in your particular situation, this may require some tweaking.

like image 102
p.s.w.g Avatar answered Feb 20 '26 11:02

p.s.w.g