I'm writing a web service in C#. For that i am making API calls to PVGIS . This API documentation for specifies it responds with BASIC TEXT data or CSV data but the API response gives tabular view in any case. 文档指定它使用BASIC TEXT数据或CSV数据进行响应,但是在任何情况下,API响应均提供表格视图。 I need this response converted to c# array or object.
I've tried all methods people have specified in answers to other similar questions.
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
...
I'm using this
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(response.Content);
And the response i get is
"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"
I expect the output to be either JSON object that i can convert to C# object or if possible converting response directly to C# array or object.
Some web services present data in multiple formats. So the http request can say which data type it needs and the web service will provide data in that format. https://restfulapi.net/content-negotiation/
For your question I think if you add the header "Accept: application/json" to your http request, the web service will give you data in json format.
Given that you are already using the ToObject, consider simplifying the code for readability and the advantage of not having to convert anything, you can just create a class with 3 property in your case and use this code( You should keep in mind that the fields are built with the class properties according to the Json output):
your Class:
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>>();
The actual response appears to be of no concern so using a dynamic simplifies things. Converting back to strongly typed objects by calling ToObject was a good choice and should work out fine.
Wow, if you can request the API to respond with json or xml you can make short work of this - but if it really is just tabular text then life becomes a bit more complicated as you need to manually parse the data and convert it into objects.
Let's consider an example object that you might target, containing a collection of another custom type. (Have used list for convenience as we may not know the length of the expected data, you can substitute this for a HashSet if preferred, or even swap things around a bit make this a private collection with a public method that returns it as an array if array is what you need to make use of etc. Also you can change the member types as needed).
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>();
}
}
Here is the nested object.
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;
}
}
Here is some shortened sample data.
// 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";
Now to parse the sample data with Regex.... Disclaimer - code for example only and contains minimal checking which assumes the data format is consistent. Also my Regex is really basic!
// 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);
}
}
Again, just to emphasise, lots of room for improvement here, happy for anyone to make better work of this!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.