提问人:António Pragana 提问时间:6/2/2023 最后编辑:António Pragana 更新时间:6/6/2023 访问量:34
是否可以使用 C# 派生类反序列化来自不同 Web 源的 JSON?
Is it possible to deserialize JSON from different web sources with C# derived classes?
问:
意向:从不同的 Web 源接收 json 格式的数据,返回不同的数据列表,并对其进行反序列化。
几乎可以肯定这是一个新手 C# 问题:( 没有派生类的经验...... 也许我正在尝试一个不可能的数据操作......
1 - 创建了一个带有抽象索引的抽象数据类(通过命名字符串访问数据)。然后创建 2 个派生类,其中包含每个源的字段。到目前为止没有问题。
public abstract class Data
{
public abstract object this[string index] { get; set; }
}
public class Type1 : Data
{
public DateTime DATA_COTA { get; set; }
public string MOEDABASE { get; set; }
public override object this[string index]
{
get
{
switch (index.Substring(1))
{
case "DATA_COTA":
return DATA_COTA;
case "MOEDABASE":
return MOEDABASE;
default:
throw new InvalidOperationException($"campo {index} inválido");
}
}
set
{
;
}
}
}
public class Type2 : Data
{
public string MOEDA { get; set; }
public decimal VALFIX { get; set; }
public override object this[string index]
{
get
{
switch (index.Substring(1))
{
case "MOEDA":
return MOEDA;
case "VALFIX":
return VALFIX;
default:
throw new InvalidOperationException($"campo {index} inválido");
}
}
set
{
;
}
}
}
2 - 创建一个抽象根类,其中包含一个公共字符串字段 (odatacontext) 和从每个站点返回的字段列表。由于我没有在每个类定义中提及每种类型,因此我认为它永远不会起作用。我尝试了很多变化/技巧,但这是唯一一个可以编译但不起作用的版本:(
public abstract class Root
{
[JsonProperty("@odata.context")]
public string odatacontext { get; set; }
public abstract List<Data> value { get; set; }
}
public class RootType1 : Root
{
public override List<Data> value
{
get
{
return this.value;
}
set
{
//List<Type1> value = value.Select(s => (Type1)s).ToList();
this.value = value;
}
}
}
public class RootType2 : Root
{
public override List<Data> value
{
get
{
return this.value;
}
set
{
//List<Type2> value = value.Select(s => (Type2)s).ToList();
this.value = value;
}
}
}
3 - 最后是代码......引用 obj.value 时出现堆栈溢出
using (HttpClient httpClient = new HttpClient())
{
HttpResponseMessage httpResponseMessage = httpClient.SendAsync(httpRequestMessage).Result;
string json = httpResponseMessage.Content.ReadAsStringAsync().Result;
if (!httpResponseMessage.IsSuccessStatusCode)
throw new InvalidOperationException(json);
Root obj;
switch (name)
{
case "Type1":
obj = JsonConvert.DeserializeObject<RootType1>(json);
break;
case "Type2":
obj = JsonConvert.DeserializeObject<RootType2>(json);
break;
default:
throw new InvalidOperationException($"{name} não previsto");
}
foreach (var item in **obj.value**)
{
foreach (SqlParameter param in cmdUPD.Parameters)
{
string paramName = param.ParameterName;
if (name != "@RETURN_VALUE")
cmdUPD.Parameters[paramName].Value = item[paramName];
}
cmdUPD.ExecuteNonQuery();
}
}
正如我被要求提供 json 一样......然后我必须发送“真实的东西”...... 我正在发送实际的解决方案(1 和 2 ...工作,但使用重复的代码)......然后 JSON 流......然后是预期的解决方案(4 和 5)。我没有显示派生类(或任何其他解决方案),因为我不知道如何:( 目的是让所有(我有几个)类 Root* 派生自一个 Root 类,以及一段模糊的代码,只改变 json 反序列化。
1 - ACTUAL 类定义
public abstract class Data
{
public abstract object this[string index] { get; set; }
}
public class Câmbios : Data
{
public int SGC_ID { get; set; }
public DateTime DtCâmbio { get; set; }
public string MdaBase { get; set; }
public string Mda { get; set; }
public decimal Fixing { get; set; }
public override object this[string index]
{
get
{
switch (index.Substring(1))
{
case "DtCâmbio":
return DtCâmbio;
case "MdaBase":
return MdaBase;
case "Mda":
return Mda;
case "Fixing":
return Fixing;
default:
throw new InvalidOperationException($"campo {index} inválido");
}
}
set
{
;
}
}
}
public class RootCâmbios
{
[JsonProperty("@odata.context")]
public string odatacontext { get; set; }
public List<Câmbios> value { get; set; }
}
public class Índice : Data
{
public int SGC_ID { get; set; }
public string Indexante { get; set; }
public DateTime Data { get; set; }
public decimal Valor { get; set; }
public string OmitirLista { get; set; }
public override object this[string index]
{
get
{
switch (index.Substring(1))
{
case "Indexante":
return Indexante;
case "Data":
return Data;
case "Valor":
return Valor;
case "OmitirLista":
return OmitirLista;
default:
throw new InvalidOperationException($"campo {index} inválido");
}
}
set
{
;
}
}
}
public class RootÍndices
{
[JsonProperty("@odata.context")]
public string odatacontext { get; set; }
public List<Índice> value { get; set; }
}
2 - 实际程序(复制:()
switch (name)
{
case "Câmbios":
//RESOLVER ... analisar se há forma de consumir o registo no caso do odatacontext ser null ... ler Root ???
//Root obj = JsonConvert.DeserializeObject<RootCâmbios>(json);
RootCâmbios objCâmbios = JsonConvert.DeserializeObject<RootCâmbios>(json);
if (!objCâmbios.odatacontext.StartsWith($"{urlBase}/$metadata#{SGC_name}"))
throw new InvalidOperationException("falha na validação do contexto");
foreach (Data item in objCâmbios.value)
{
foreach (SqlParameter param in cmdINS.Parameters)
{
string paramName = param.ParameterName;
if (!(param.ParameterName == "@RETURN_VALUE" || param.ParameterName == "@EXEC_Dia"))
cmdINS.Parameters[paramName].Value = item[paramName];
}
cmdINS.ExecuteNonQuery();
}
break;
case "Índices":
RootÍndices objÍndices = JsonConvert.DeserializeObject<RootÍndices>(json);
if (objÍndices.odatacontext != null)
{
if (!objÍndices.odatacontext.StartsWith($"{urlBase}/$metadata#{SGC_name}"))
throw new InvalidOperationException("falha na validação do contexto");
foreach (Data item in objÍndices.value)
{
foreach (SqlParameter param in cmdINS.Parameters)
{
string paramName = param.ParameterName;
if (!(param.ParameterName == "@RETURN_VALUE" || param.ParameterName == "@EXEC_Dia"))
cmdINS.Parameters[paramName].Value = item[paramName];
}
cmdINS.ExecuteNonQuery();
}
}
break;
default:
throw new InvalidOperationException($"{name} não previsto");
}
3 - JSON 数据
Câmbios {“@odata.context”:“http://gasgc.montepio.com/odatacustom/maintenancedata/$metadata#fixingrates#9ee42a020a03ff123ae687ecfc1ce91ee9e2768e0a1274c518516e62c66fcc175b8adda21cf69cd59a70afcc8a08c334cda15b00f1c78239c8e1430f5f363da3”,“value”:[{“fixingrates_ID”:1,“DtC\u00e2mbio”:“2023-05-26T00:00:00+01:00”,“MdaBase”:“USD”,“Mda”:“EUR”,“Fixing”:1.075100000000000},{“fixingrates_ID”:2,“DtC\u00e2mbio”:“2023-05-26T00:00:00+01:00”,“MdaBase”:“GBP“,”Mda“:”EUR“,”Fixing“:0.868130000000000},{”fixingrates_ID“:3,”DtC\u00e2mbio“:”2023-05-26T00:00:00+01:00“,”MdaBase“:”JPY“,”Mda“:”EUR“,”Fixing“:2023-05-26T00:00:00:00:00:JPY”,“Mda”:“EUR”,“Fixing”::::2023-05-26T00:00:00+01:00“,”MdaBase“:”JPY“,”Mda“:”EUR“,”Fixing“:2023-05-26T00-26T00:00:00:00:00”,“MdaBase”:“JPY”,“Mda”:“EUR”,“Fixing”:::2023-05-26T00-00:00:00:00“,”MdaBase“:”JPY“,”Mda“:”EUR“,”Fixing“:2023-05-05-26T00:00:00:00:00”,“MdaBase”:“JPY”,“Mda”:“EUR”,“Fixing”:2023-05-26T00:00:00:00:00+01:00“,”MdaBase“:”JPY“,”Mda“:”EUR“,”Fixing“:2023-05-26T00:00:00:00+01:00”,“MdaBase”:“JPY”,“Mda”:“EUR”,“Fixing”:2023-05-26T00:00:00:00+01:00“,”MdaBase“:”JPY“,”Mda“:”EUR“,”Fixing“:2023-05-26T00-00:00:00:00+01:00”,“MdaBase”:“JPY”,“Mda”:“EUR”,“Fixing”:2023-05-26T00:00:00:00:00+01:00“,”MdaBase“:”JPY“,”Mda“:”EUR“,”Fixing“:2023-05-26T00:00:00:00+01:00”,“MdaBase150.2400000000000000},{”fixingrates_ID“:4,”DtC\u00e2mbio“:”2023-05-26T00:00:00+01:00“,”MdaBase“:”SEK“,”Mda“:”EUR“,”Fixing“:11.5280000000000000},{”fixingrates_ID“:5,”DtC\u00e2mbio“:”2023-05-26T00:00:00+01:00“,”MdaBase“:”CHF“,”Mda“:”EUR“,”Fixing“:0.97070000000000000},{”fixingrates_ID“:6,”DtC\u00e2mbio“:”2023-05-26T00:00:00+01:00“,”MdaBase“:”NOK“,”Mda“:”EUR“,”Fixing“:11.8218000000000000},{”fixingrates_ID“:7,”DtC\u00e2mbio“:”2023-05-26T00:00:00+01:00“,”MdaBase“:”DKK“,”Mda“:”EUR“,”Fixing“:7.448900000000000},{”fixingrates_ID“:8,”DtC\u00e2mbio“:”2023-05-26T00:00:00+01:00“,”MdaBase“:”BRL“,”Mda“:”EUR“,”Fixing“:5.38780000000000000}]}
Índices {“@odata.context”:“http://gasgc.montepio.com/odatacustom/maintenancedata/$metadata#interestindexvalues#8f2b6731ceade8d332dec84a53057e906a421270f07a52de17d3fc5e1160c1700c454af1437737f8e674fd151e4df4ad57da7ea78a66d81aa54177609cb7fd77”,“value”:[{“interestindexvalues_ID”:1,“Indexante”:“77”,“Data”:“2023-05-25T00:00:00+01:00”,“Valor”:3.45700000,“OmitirLista”:“N”}]}
4 - 预期的根基类
public abstract class Root
{
[JsonProperty("@odata.context")]
public string odatacontext { get; set; }
public abstract List<Data> value { get; set; }
}
5 - 预期的代码
Root obj;
switch (name)
{
case "Câmbios":
obj = JsonConvert.DeserializeObject<RootCâmbios>(json);
break;
case "Índices":
obj = JsonConvert.DeserializeObject<RootÍndices>(json);
break;
default:
throw new InvalidOperationException($"{name} não previsto");
}
if (!obj.odatacontext.StartsWith($"{urlBase}/$metadata#{SGC_name}"))
throw new InvalidOperationException("falha na validação do contexto");
foreach (Data item in obj.value)
{
foreach (SqlParameter param in cmdINS.Parameters)
{
string paramName = param.ParameterName;
if (!(param.ParameterName == "@RETURN_VALUE" || param.ParameterName == "@EXEC_Dia"))
cmdINS.Parameters[paramName].Value = item[paramName];
}
cmdINS.ExecuteNonQuery();
}
答: 暂无答案
评论