Xamarinを使用しているアンドロイドアプリケーションでAPIから情報を取得しようとしています。APIリクエストはアプリケーションで失敗しますが、ブラウザで動作します
そしてそれは火格子で動作します!生成されたリンクをChromeに貼り付けるか、Chrome拡張機能Postmanを使用すると正確に必要な情報が得られますが、アプリケーションでは機能しません。
アプリケーションはpoc状態なので、 ILocationListener
を実装し、GPSが3秒ごとに更新されますが、ここではコードの興味深い部分である要求アクティビティ:
public void OnLocationChanged(Location location) {
var lat = location.Latitude;
var lon = location.Longitude;
_lat.Text = "lat: " + lat;
_lon.Text = "lon: " + lon;
// get the vegReference (roadReference) based on the lat & lon
var url = "https://www.vegvesen.no/nvdb/api/vegreferanse/koordinat?lon=" + lon.ToString("") + "&lat=" + lat.ToString("") + "&geometri=WGS84";
// ex: https://www.vegvesen.no/nvdb/api/vegreferanse/koordinat?lon=10.399547&lat=63.354658&geometri=WGS84
var json = new JSONObject(Get(url));
Log.Debug("url", url);
Log.Debug("json", json.ToString());
if (json.GetString("kommuneNr") == "0") return; // bug in API?
var kommuneNr = json.GetString("kommuneNr");
var vegReferanse = json.GetString("visningsNavn");
// get the object id 105 (speed limit) on set vegReference
// API dok: https://www.vegvesen.no/nvdb/apidokumentasjon/#/get/vegobjekter
var url2 = "https://www.vegvesen.no/nvdb/api/v2/vegobjekter/105?vegreferanse=" + vegReferanse.Replace(" ", "") + "&inkluder=lokasjon&segmentering=false";
// ex. https://www.vegvesen.no/nvdb/api/v2/vegobjekter/105?vegreferanse=PV3133HP1m73&inkluder=lokasjon&segmentering=false
// this (url2) is the one that fails
Log.Debug("url2", url2);
var json2 = new JSONObject(Get(url2));
Log.Debug("json2", json2.ToString());
// get the speed limit with the heighest id (this should be the latest one (FYI: speedlimits have changed over the years, all speed limits are in the database for historical reasons(?)))
var objs = json2.GetJSONArray("vegObjekter");
var list = new List<JSONObject>();
// getting a list of possible objects based on the kommuneNr (because for some f*ced up reason the result returns objects in other kommunes aswell...)
for (int i = 0; i < objs.Length() - 1; i++)
{
if (objs.GetJSONObject(i).GetJSONObject("lokasjon").GetJSONArray("kommuner").GetString(0) == kommuneNr)
list.Add(objs.GetJSONObject(i));
}
if (list.Count == 0) return;
var url3 = list[list.Count - 1].GetString("href");
// ex. https://www.vegvesen.no/nvdb/api/v2/vegobjekter/105/276790644
Log.Debug("url3", url3);
var json3 = new JSONObject(Get(url3));
Log.Debug("json3", json3.ToString());
// set the speed-limit to the textview.
var res = json3.GetJSONArray("egenskaper").GetJSONObject(0).GetString("verdi");
_tvSl.Text = res + " km/t";
}
そしてGet
は、基本的には単なる文字列として応答を取得OnLocationChanged
、内部で呼び出さbeeingて-method :
private string Get(string url)
{
var request = WebRequest.Create(url);
var sb = new StringBuilder();
var response = (HttpWebResponse)request.GetResponse();
using (var sr = new StreamReader(response.GetResponseStream()))
{
sb.Append(sr.ReadToEnd());
}
return sb.ToString();
}
URL2-要求からの応答はこれです:
System.Net.WebException: The remote server returned an error: (500) Internal Server Error.
私の質問はこれです。なぜリンク(ref url2)はブラウザで動作し、アプリケーションでは動作しませんか?
この件に関するお手伝いやご指摘をお待ちしております。 また、GitHubのプロジェクトへのリンク:https://github.com/Nemeas/alfaOmega
Hey!ここのAPI作家の一人。私もこのケースの最下部に行きたいです。私はこの時点であなたのXamarinコードを実行することができませんが、プログラミングの参考にしたいと思います。 Javaプラットフォーム用のオープンソースクライアントを公開しました。ソースコードはhttps://github.com/nvdb-vegdata/nvdb-api-client – matsa
@matsaのチップを与えるかもしれないので、私は実際に(最終的に) 'Accept:application/json'をリクエスト。しかし、 'request'Headers.Add(HttpRequestHeader.Accept、" application/json ")'が動作しなかったので、私は 'Get'メソッドで' HttpWebRequest'を使用しなければなりませんでした(私は有効なプロパティ値Enum/Const(?)HttpRequestHeader.Acceptの代わりに文字列値 "accept"を使ってみましたが、 'HttpWebRequest'は' accept'を以下のようにプロパティとして公開しています: 'request.Accept = "アプリケーション/ json"。最初のurlには必要ありませんでした – Nemeas