[英]How to convert API Json response to C# Array?
我正在用C#编写Web服务。 为此,我正在对PVGIS进行API调用。 此API 月度太阳辐射值 文档指定它使用BASIC TEXT数据或CSV数据进行响应,但是在任何情况下,API响应均提供表格视图。 我需要将此响应转换为c#数组或对象。
我尝试了人们在回答其他类似问题时指定的所有方法。
API回应:
Latitude (decimal degrees): 45.000
Longitude (decimal degrees): 8.000
Radiation database: PVGIS-CMSAF
Optimal slope angle (deg.):
Year Month Hh
2005 Jan 56.5
2005 Feb 75.7
2005 Mar 118
2005 Apr 131
2005 May 193
2005 Jun 211
2005 Jul 217
2005 Aug 179
2005 Sep 115
2005 Oct 72.9
2005 Nov 42.4
2005 Dec 39.4
2006 Jan 51.3
2006 Feb 58.6
2006 Mar 118
2006 Apr 147
2006 May 167
2006 Jun 215
...
我正在使用这段代码
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(response.Content);
我得到的回应是
"Latitude (decimal degrees):\t0.000\r\nLongitude (decimal degrees):\t0.000\r\nRadiation database:\tPVGIS-CMSAF\r\nOptimal slope angle (deg.):\t\r\n\r\nYear\t\t Month\t\tHh\r\n2005\t\tJan\t\t0\r\n2005\t\tFeb\t\t0\r\n2005\t\tMar\t\t0\r\n2005\t\tApr\t\t0\r\n2005\t\tMay\t\t0\r\n2005\t\tJun\t\t0\r\n2005\t\tJul\t\t0\r\n2005\t\tAug\t\t0\r\n2005\t\tSep\t\t0\r\n2005\t\tOct\t\t0\r\n2005\t\tNov\t\t0\r\n2005\t\tDec\t\t0\r\n2006\t\tJan\t\t0\r\n2006\t\tFeb\t\t0\r\n2006\t\tMar\t\t0\r\n2006\t\tApr\t\t0\r\n2006\t\tMay\t\t0\r\n2006\t\tJun\t\t0\r\n2006\t\tJul\t\t0\r\n2006\t\tAug\t\t0\r\n2006\t\tSep\t\t0\r\n2006\t\tOct\t\t0\r\n2006\t\tNov\t\t0\r\n2006\t\tDec\t\t0\r\n2007\t\tJan\t\t0\r\n2007\t\tFeb\t\t0\r\n2007\t\tMar\t\t0\r\n2007\t\tApr\t\t0\r\n2007\t\tMay\t\t0\r\n2007\t\tJun\t\t0\r\n2007\t\tJul\t\t0\r\n2007\t\tAug\t\t0\r\n2007\t\tSep\t\t0\r\n2007\t\tOct\t\t0\r\n2007\t\tNov\t\t0\r\n2007\t\tDec\t\t0\r\n2008\t\tJan\t\t0\r\n2008\t\tFeb\t\t0\r\n2008\t\tMar\t\t0\r\n2008\t\tApr\t\t0\r\n2008\t\tMay\t\t0\r\n2008\t\tJun\t\t0\r\n2008\t\tJul\t\t0\r\n2008\t\tAug\t\t0\r\n2008\t\tSep\t\t0\r\n2008\t\tOct\t\t0\r\n2008\t\tNov\t\t0\r\n2008\t\tDec\t\t0\r\n2009\t\tJan\t\t0\r\n2009\t\tFeb\t\t0\r\n2009\t\tMar\t\t0\r\n2009\t\tApr\t\t0\r\n2009\t\tMay\t\t0\r\n2009\t\tJun\t\t0\r\n2009\t\tJul\t\t0\r\n2009\t\tAug\t\t0\r\n2009\t\tSep\t\t0\r\n2009\t\tOct\t\t0\r\n2009\t\tNov\t\t0\r\n2009\t\tDec\t\t0\r\n2010\t\tJan\t\t0\r\n2010\t\tFeb\t\t0\r\n2010\t\tMar\t\t0\r\n2010\t\tApr\t\t0\r\n2010\t\tMay\t\t0\r\n2010\t\tJun\t\t0\r\n2010\t\tJul\t\t0\r\n2010\t\tAug\t\t0\r\n2010\t\tSep\t\t0\r\n2010\t\tOct\t\t0\r\n2010\t\tNov\t\t0\r\n2010\t\tDec\t\t0\r\n2011\t\tJan\t\t0\r\n2011\t\tFeb\t\t0\r\n2011\t\tMar\t\t0\r\n2011\t\tApr\t\t0\r\n2011\t\tMay\t\t0\r\n2011\t\tJun\t\t0\r\n2011\t\tJul\t\t0\r\n2011\t\tAug\t\t0\r\n2011\t\tSep\t\t0\r\n2011\t\tOct\t\t0\r\n2011\t\tNov\t\t0\r\n2011\t\tDec\t\t0\r\n2012\t\tJan\t\t0\r\n2012\t\tFeb\t\t0\r\n2012\t\tMar\t\t0\r\n2012\t\tApr\t\t0\r\n2012\t\tMay\t\t0\r\n2012\t\tJun\t\t0\r\n2012\t\tJul\t\t0\r\n2012\t\tAug\t\t0\r\n2012\t\tSep\t\t0\r\n2012\t\tOct\t\t0\r\n2012\t\tNov\t\t0\r\n2012\t\tDec\t\t0\r\n2013\t\tJan\t\t0\r\n2013\t\tFeb\t\t0\r\n2013\t\tMar\t\t0\r\n2013\t\tApr\t\t0\r\n2013\t\tMay\t\t0\r\n2013\t\tJun\t\t0\r\n2013\t\tJul\t\t0\r\n2013\t\tAug\t\t0\r\n2013\t\tSep\t\t0\r\n2013\t\tOct\t\t0\r\n2013\t\tNov\t\t0\r\n2013\t\tDec\t\t0\r\n2014\t\tJan\t\t0\r\n2014\t\tFeb\t\t0\r\n2014\t\tMar\t\t0\r\n2014\t\tApr\t\t0\r\n2014\t\tMay\t\t0\r\n2014\t\tJun\t\t0\r\n2014\t\tJul\t\t0\r\n2014\t\tAug\t\t0\r\n2014\t\tSep\t\t0\r\n2014\t\tOct\t\t0\r\n2014\t\tNov\t\t0\r\n2014\t\tDec\t\t0\r\n2015\t\tJan\t\t0\r\n2015\t\tFeb\t\t0\r\n2015\t\tMar\t\t0\r\n2015\t\tApr\t\t0\r\n2015\t\tMay\t\t0\r\n2015\t\tJun\t\t0\r\n2015\t\tJul\t\t0\r\n2015\t\tAug\t\t0\r\n2015\t\tSep\t\t0\r\n2015\t\tOct\t\t0\r\n2015\t\tNov\t\t0\r\n2015\t\tDec\t\t0\r\nHh: Irradiation on horizontal plane (kWh/m2)\r\n\r\nPVGIS (c) European Communities, 2001-2016"
我希望输出是可以转换为C#对象的JSON对象,或者尽可能将响应直接转换为C#数组或对象。
一些Web服务以多种格式显示数据。 因此,http请求可以说出它需要哪种数据类型,Web服务将以该格式提供数据。 https://restfulapi.net/content-negotiation/
对于您的问题,我想如果您将标头“ Accept:application / json”添加到http请求中,则Web服务将以json格式提供数据。
鉴于您已经在使用ToObject,请考虑简化代码的可读性以及无需转换任何内容的优点,您可以在这种情况下仅创建一个具有3个属性的类并使用此代码(您应牢记该字段是根据Json输出使用类属性构建的:
你的班:
public class Monthly
{
public string Year { get; set; }
public string Month { get; set; }
public string Hh { get; set; }
}
var contentJson = await SendRequest(request);
dynamic response = JsonConvert.DeserializeObject(contentJson);
List<Monthly> organizations = response.organizations.ToObject<List<Monthly>>();
实际的响应似乎无关紧要,因此使用动态方法可以简化操作。 通过调用ToObject转换回强类型对象是一个不错的选择,应该可以解决。
哇,如果您可以请求API使用json或xml进行响应,则可以简化此工作-但如果实际上只是表格文本,则生活会变得更加复杂,因为您需要手动解析数据并将其转换为对象。
让我们考虑一个可能面向的示例对象,其中包含另一个自定义类型的集合。 (使用清单是为了方便,因为我们可能不知道期望数据的长度,如果需要,可以将其替换为HashSet,或者甚至交换一些东西以使其成为带有公共方法的私有集合,该方法将其作为数组返回if array是您需要使用的对象等等。也可以根据需要更改成员类型)。
public class ApiData
{
public decimal Latitude { get; set; }
public decimal Longitude { get; set; }
public string RadiationDatabase { get; set; }
public List<ApiSlopeAngle> OptimalSlopeAngle { get; set; }
public ApiData()
{
OptimalSlopeAngle = new List<ApiSlopeAngle>();
}
}
这是嵌套的对象。
public class ApiSlopeAngle
{
public int Year { get; set; }
public string Month { get; set; }
public decimal Hh { get; set; }
public ApiSlopeAngle(int year, string month, decimal hh)
{
Year = year;
Month = month;
Hh = hh;
}
}
这是一些简化的样本数据。
// Sample data
string apiStringData = "Latitude (decimal degrees):\t45.000\r\nLongitude (decimal degrees):\t8.000\r\nRadiation database:\tPVGIS-CMSAF\r\nOptimal slope angle (deg.):\t\r\n\r\nYear\t\t Month\t\tHh\r\n2005\t\tJan\t\t56.5\r\n2005\t\tFeb\t\t75.7\r\n2005\t\tMar\t\t118\r\n2005\t\tApr\t\t131\r\n2005\t\tMay\t\t193\r\n2005\t\tJun\t\t211\r\n2005\t\tJul\t\t217\r\n2005\t\tAug\t\t179\r\n2005\t\tSep\t\t115\r\n2005\t\tOct\t\t72.9\r\n2005\t\tNov\t\t42.4\r\nHh: Irradiation on horizontal plane(kWh/ m2)\r\n\r\nPVGIS(c) European Communities, 2001 - 2016";
现在使用Regex ...解析示例数据。免责声明-仅作为示例的代码,其中包含最少的检查,假定数据格式一致。 另外我的Regex真的很基础!
// Define the regex patterns to use
string lattPattern = "(Latitude\\s\\(decimal\\sdegrees\\):)(\\t\\d+\\.*\\d*)";
string longPattern = "(Longitude\\s\\(decimal\\sdegrees\\):)(\\t\\d+\\.*\\d*)";
string radDbPattern = "(Radiation\\sdatabase\\:)(\\t)(PVGIS\\-CMSAF)";
string osaPattern = "((19|20)\\d{2})(\\t\\t)([A-Z]+[a-z]*)(\\t\\t\\d+\\.*\\d*)";
// Create the matches for the top-level data
var lattitude = Regex.Match(apiStringData, lattPattern);
var longitude = Regex.Match(apiStringData, longPattern);
var radDb = Regex.Match(apiStringData, radDbPattern);
// Create the result object, and populate the top-level properties
ApiData apiObject = new ApiData();
apiObject.Latitude = Convert.ToDecimal(lattitude.Groups[2].ToString());
apiObject.Longitude = Convert.ToDecimal(longitude.Groups[2].ToString());
apiObject.RadiationDatabase = radDb.Groups[3].ToString();
// Split the sample data into an array
// to make it easier to enumerate what will become the nested data
string[] apiArray = Regex.Split(apiStringData, "\r\n");
// Step through it
foreach (string s in apiArray)
{
var angle = Regex.Match(s, osaPattern, RegexOptions.IgnoreCase);
if (angle.Success == true)
{
// Create the properties
int year = Convert.ToInt32(angle.Groups[1].ToString());
string month = angle.Groups[4].ToString();
decimal hh = Convert.ToDecimal(angle.Groups[5].ToString());
// Add to the collection
ApiSlopeAngle apiDate = new ApiSlopeAngle(year, month, hh);
apiObject.OptimalSlopeAngle.Add(apiDate);
}
}
再次强调一下,这里还有很大的改进空间,任何人都可以为更好地完成此工作而感到高兴!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.