将Json解析为字符串或字符串数组?

3

我能把这些代码用泛型整合成一个方法吗?

我希望返回字符串或字符串数组,因为我的Json文件如下所示。

Json样例

所以我想做像这样的事情。

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;
}

但键的值不能是字符串数组。

它也可以是字符串。


2
这两个方法看起来完全不同,为什么你想要在这里使用泛型?而且,这些方法的意义是什么,你都扔掉了 a 的值? - maccettura
2
您似乎没有使用“a”参数。 - LarsTech
2
为什么不让你的函数每次返回一个数组呢?这会让事情变得不那么复杂。有一个成员的数组并不是世界末日。 - LarsTech
@stefan 不,我会添加更多的属性。 - Busted
1
是的,谢谢大家的回答。 :D - Busted
显示剩余8条评论
2个回答

2

不要返回两种可能的返回类型,最好的方法是将单个字符串强制转换为包含该字符串的数组。假设您无法控制Json,您可能需要编写自定义JsonConverter。以下是我快速而简单的解决方案:

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();
    }
}

然后这样调用它:

// 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

当然,在你的具体情况下,这可能需要一些微调。

1
@Stefan同意,我开始拼凑这个(实际上只是为了让自己恢复一下,因为至少有一年没深入使用Json.NET了),在看到所有评论之前。我决定还是把这个留在这里,以防对未来的读者有所帮助。 - p.s.w.g

0
使用泛型语法:
 class Program<T>
{

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

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

        return values;
    }
}

1
嗯,我认为泛型参数放错了位置。你把它放在了 Program 上,但应该放在 GetJsonValue 上。此外,展示调用语法可能会很有帮助(即如何调用 GetJsonValue 来获取字符串或字符串数组)。 - p.s.w.g
使用对象:public static object GetJsonValue(string key) { object values = lang[key].ToObject<object>();return values;} - Morteza Mousavi
1
@MortezaMousavi:感谢您的跟进。您可以[编辑]您的问题并将代码放在其中,这样其他人就更容易跟上了;-) - Stefan
我也认为应该使用GetJsonValue<T>而不是Program<T> - Stefan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接