簡體   English   中英

如何將API Json響應轉換為C#數組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM