You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin C#中如何读取包含多类型数据的JSON?

问题:Xamarin C#解析含数组的JSON数据失败

在Xamarin C#中向数据库请求数据,返回字典列表形式的JSON,但现有代码仅能处理string类型数据,无法解析数组等复杂类型,执行时报错。

原代码

if (response.IsSuccessStatusCode)
{
    string json = await response.Content.ReadAsStringAsync();
    Dictionary<string, List<Dictionary<string, string>>> reponse = JsonConvert.DeserializeObject<Dictionary<string, List<Dictionary<string, string>>>>(json);
    List<Dictionary<string, string>> resultat = reponse["reponse"];

    foreach (Dictionary<string, string> dicoProfil in resultat)
    {
        //Initialisation des variables
        string nomProfilAAjouter = dicoProfil["Usager"];
        string nomPropriete = dicoProfil["Predicat"];
        string valeurPropriete = dicoProfil["Caracteristique"];
        string dataProperty = dicoProfil["Dataproperty"];
        string valeurdata = dicoProfil["Valeurdata"];

        //Modification du profil si un profil avec le même nom existe déjà
        if ("profil:"+nomProfil==nomProfilAAjouter)
        {
            if (profils.ContainsKey(nomProfilAAjouter))
            {
                await SetProperty(nomPropriete, valeurPropriete, dataProperty, valeurdata, profils[nomProfilAAjouter]);
            }
            //Ajout du profil
            else
            {
                Profil newProfil = new Profil();
                await SetProperty(nomPropriete, valeurPropriete, dataProperty, valeurdata, newProfil);
                profils[nomProfilAAjouter] = newProfil;
            }
        }   
    }
}
return profils["profil:" + nomProfil] ; 
}

待解析的JSON结构

[
    {
        "Usager": "profil:Jean_PIERRE",
        "rdf:type": "owl:NamedIndividual",
        "profil:A_Pour_Comportement": "profil:9e7b483e_cec8_4ce7_8ae2_6e693859a043",
        "profil:A_Pour_Droit": "profil:Administrateur",
        "profil:A_Pour_Espace_Travail": "arch:IfcSpace_12783",
        "profil:A_Pour_Habitude": "profil:7228afa0_ce7b_4b76_a640_6e2ec2cbcb23",
        "profil:A_Pour_Profession": "profil:Responsable_informatique",
        "schema:givenName": "Jean",
        "schema:name": "PIERRE",
        "profil:A_Pour_Competence": [
            {"caracteristique": "profil:Cuisine", "valeurdata": "4", "predicat": "profil:Niveau_expertise"},
            {"caracteristique": "profil:Réseau", "valeurdata": "7", "predicat": "profil:Niveau_expertise"}
        ],
        "profil:A_Pour_Modèle_Usager": [
            {"caracteristique": "modele:ac63f979_aa26_4bf5_a308_b1d30bd9cbae", "valeurdata": "Modèle_Lum_Jean", "predicat": "modele:Description"},
            {"caracteristique": "modele:ac63f979_aa26_4bf5_a308_b1d30bd9cbae", "valeurdata": "Modèle Lumiere Jean", "predicat": "modele:Nom"},
            {"caracteristique": "modele:f95314a6_ffc8_4481_95a6_0ed2db5e4854", "valeurdata": "Modèle_Temp_Jean", "predicat": "modele:Description"},
            {"caracteristique": "modele:f95314a6_ffc8_4481_95a6_0ed2db5e4854", "valeurdata": "Modèle Temperature Jean", "predicat": "modele:Nom"}
        ]
    }
]

错误信息

An error occurred: 'Unexpected character encountered while parsing value: [. Path 'reponse[0].profil:A_Pour_Competence', line 1, position 545.'. Callstack: ' at Newtonsoft.Json.JsonTextReader.ReadStringValue (Newtonsoft.Json.ReadType readType)


解决方案

方法1:使用JToken/JObject动态解析(快速适配复杂结构)

将强类型字典替换为Newtonsoft.Json的JObject/JToken类型,自动适配JSON中的字符串、数组、对象等所有类型:

if (response.IsSuccessStatusCode)
{
    string json = await response.Content.ReadAsStringAsync();
    // JSON根节点是数组,先反序列化为JArray
    JArray resultat = JsonConvert.DeserializeObject<JArray>(json);

    foreach (JObject dicoProfil in resultat)
    {
        string nomProfilAAjouter = dicoProfil["Usager"].Value<string>();
        
        if ("profil:" + nomProfil == nomProfilAAjouter)
        {
            Profil targetProfil;
            // 查找或创建目标Profil实例
            if (!profils.TryGetValue(nomProfilAAjouter, out targetProfil))
            {
                targetProfil = new Profil();
                profils[nomProfilAAjouter] = targetProfil;
            }

            // 遍历所有属性,区分类型处理
            foreach (var property in dicoProfil.Properties())
            {
                string propName = property.Name;
                JToken propValue = property.Value;

                // 处理字符串类型字段
                if (propValue.Type == JTokenType.String)
                {
                    await SetProperty(propName, propValue.Value<string>(), null, null, targetProfil);
                }
                // 处理数组类型字段
                else if (propValue.Type == JTokenType.Array)
                {
                    foreach (JObject item in propValue.Children<JObject>())
                    {
                        string predicat = item["predicat"].Value<string>();
                        string caracteristique = item["caracteristique"].Value<string>();
                        string valeurdata = item["valeurdata"].Value<string>();
                        await SetProperty(predicat, caracteristique, null, valeurdata, targetProfil);
                    }
                }
            }
        }
    }
}
return profils["profil:" + nomProfil];

方法2:创建匹配JSON结构的实体类(强类型,类型安全)

根据JSON结构定义对应的C#实体类,让Newtonsoft.Json自动完成类型映射:

// 根节点数组的条目类
public class ProfilEntry
{
    [JsonProperty("Usager")]
    public string Usager { get; set; }

    [JsonProperty("rdf:type")]
    public string RdfType { get; set; }

    [JsonProperty("profil:A_Pour_Comportement")]
    public string APourComportement { get; set; }

    [JsonProperty("profil:A_Pour_Droit")]
    public string APourDroit { get; set; }

    [JsonProperty("profil:A_Pour_Espace_Travail")]
    public string APourEspaceTravail { get; set; }

    [JsonProperty("profil:A_Pour_Habitude")]
    public string APourHabitude { get; set; }

    [JsonProperty("profil:A_Pour_Profession")]
    public string APourProfession { get; set; }

    [JsonProperty("schema:givenName")]
    public string GivenName { get; set; }

    [JsonProperty("schema:name")]
    public string Name { get; set; }

    [JsonProperty("profil:A_Pour_Competence")]
    public List<CompetenceItem> APourCompetence { get; set; }

    [JsonProperty("profil:A_Pour_Modèle_Usager")]
    public List<ModeleUsagerItem> APourModeleUsager { get; set; }
}

// Competence数组的条目类
public class CompetenceItem
{
    [JsonProperty("caracteristique")]
    public string Caracteristique { get; set; }

    [JsonProperty("valeurdata")]
    public string Valeurdata { get; set; }

    [JsonProperty("predicat")]
    public string Predicat { get; set; }
}

// Modèle Usager数组的条目类
public class ModeleUsagerItem
{
    [JsonProperty("caracteristique")]
    public string Caracteristique { get; set; }

    [JsonProperty("valeurdata")]
    public string Valeurdata { get; set; }

    [JsonProperty("predicat")]
    public string Predicat { get; set; }
}

修改解析代码:

if (response.IsSuccessStatusCode)
{
    string json = await response.Content.ReadAsStringAsync();
    List<ProfilEntry> resultat = JsonConvert.DeserializeObject<List<ProfilEntry>>(json);

    foreach (ProfilEntry entry in resultat)
    {
        if ("profil:" + nomProfil == entry.Usager)
        {
            Profil targetProfil;
            if (!profils.TryGetValue(entry.Usager, out targetProfil))
            {
                targetProfil = new Profil();
                profils[entry.Usager] = targetProfil;
            }

            // 处理普通字符串属性
            await SetProperty("rdf:type", entry.RdfType, null, null, targetProfil);
            await SetProperty("profil:A_Pour_Comportement", entry.APourComportement, null, null, targetProfil);
            // 其他普通属性同理补充

            // 处理Competence数组
            foreach (var comp in entry.APourCompetence)
            {
                await SetProperty(comp.Predicat, comp.Caracteristique, null, comp.Valeurdata, targetProfil);
            }

            // 处理Modèle Usager数组
            foreach (var modele in entry.APourModeleUsager)
            {
                await SetProperty(modele.Predicat, modele.Caracteristique, null, modele.Valeurdata, targetProfil);
            }
        }
    }
}
return profils["profil:" + nomProfil];

关键说明

  • 原代码报错核心原因:强制将所有JSON值解析为string,但JSON中存在数组类型,解析器无法完成类型转换。
  • 方法1适合动态/复杂JSON场景,灵活性高;方法2适合结构固定的场景,类型安全、可读性更强。

内容的提问来源于stack exchange,提问作者Antoine21000

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 17:44:55