Nemeas Nemeas - 1 year ago 81
reST (reStructuredText) Question

API request fails in application, but works in browser

So I am trying to get some information from an API (that I have no control over) in my android-application using Xamarin.

And it works grate! I get exactly the information I want if I paste the generated links into Chrome, or use the Chrome extension Postman, but it does not work in my application..

The application is in poc state, so everything is inside the main activity which implements the

and requests gps updates every 3 seconds, but here is the interesting part of the code:

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 = "" + lon.ToString("") + "&lat=" + lat.ToString("") + "&geometri=WGS84";

// ex:

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:
var url2 = "" + vegReferanse.Replace(" ", "") + "&inkluder=lokasjon&segmentering=false";

// ex.

// 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)

if (list.Count == 0) return;

var url3 = list[list.Count - 1].GetString("href");

// ex.

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";


And the
-method beeing called inside the
, which basically just gets the response as a string:

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()))
return sb.ToString();

The response from the url2-request is this:

System.Net.WebException: The remote server returned an error: (500) Internal Server Error.

My question is this; why does the link (ref url2) work in a browser, and not in the application.

Any help or pointers on this matter will be appreciated!
Also: link to the project on GitHub:

Answer Source

Ok, so after a ton of trial and errors I figured out that the problem was that there was a missing header; accept: application/json (it seems like this is only a case for the v2 of this api(?)). I tried to add the header using the WebRequest, but I kept getting an error whenever I reached the line where the header would be added. However there is this other WebRequest called HttpWebRequest where the accept is exposed as a property instead of through a list, and this works. So the only change I had to make was on the Get method, that ended up like this:

public static string Get(string url)
        // casting request to HttpWebRequest to expose Accept as a property
        var request = (HttpWebRequest)WebRequest.Create(url); 
        request.Accept = "application/json";

        var sb = new StringBuilder();

        // getting the response
        var response = (HttpWebResponse)request.GetResponse();

        using (var sr = new StreamReader(response.GetResponseStream()))

        var res = sb.ToString();

        // returning the response as a string
        return res;
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download