Reputation: 794
I'm trying to call openrouteservice api in vb.net and therefore tried to follow the documentation/examples. The example shows below code as working example:
Sub Main(args As String())
Dim request = TryCast(System.Net.WebRequest.Create("https://api.openrouteservice.org/v2/directions/driving-car/gpx"), System.Net.HttpWebRequest)
request.Method = "POST"
request.Accept = "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8"
request.Headers.Add("Authorization", "xxxxMYKEYxxxx")
request.Headers.Add("Content-Type", "application/json; charset=utf-8")
Using writer = New System.IO.StreamWriter(request.GetRequestStream())
Dim byteArray As Byte() = System.Text.Encoding.UTF8.GetBytes({"coordinates:[[8.681495,49.41461],[8.686507,49.41943],[8.687872,49.420318]]"})
request.ContentLength = byteArray.Length
writer.Write(byteArray)
writer.Close()
End Using
Dim responseContent As String
Using response = TryCast(request.GetResponse(), System.Net.HttpWebResponse)
Using reader = New System.IO.StreamReader(response.GetResponseStream())
responseContent = reader.ReadToEnd()
Console.WriteLine(responseContent.ToString())
End Using
End Using
End Sub
The example shows that the content of the request body should be the following:
{"coordinates":[[8.681495,49.41461],[8.686507,49.41943],[8.687872,49.420318]]}
But when running the example i get the following error:
'The remote server returned an error: (500) Internal Server Error.'
So i figured that the request fails because of the invalid Json. My question is how to create a JSON resulting in the same as in the example-JSON provided above?
Upvotes: 1
Views: 11467
Reputation: 32248
The API is expecting a JSON object, representing an array of arrays of double values, as the content of the HttpRequest, encoded as an UTF-8 string, sent as a byte array.
This collection can be represented by a List(Of List(Of Double)
Property Type of a .Net class:
' Note that JavaScriptSrializer might ignore <JsonProperty>,
' so use lower case, since the Web API is case-sensitive
Friend Class MyObject
<JsonProperty("coordinates")>
Public Property coordinates As List(Of List(Of Double))
End Class
After this, we just need to fill the List:
Dim myobj = New MyObject() With {
.Coordinates = New List(Of List(Of Double)) From {
New List(Of Double)({8.681495, 49.41461}),
New List(Of Double)({8.686507, 49.41943}),
New List(Of Double)({8.687872, 49.420318})
}
}
And serialize it, with either Json.Net (install the NuGet package via NuGet Package Manager) or JavaScriptSerializer (or any other JSON serializer available):
JavaScriptSerializer
requires a Project reference to System.Web.Extension
and to import System.Web.Script.Serialization
.
' Using Json.Net
Dim Json As String = JsonConvert.SerializeObject(myobj)
' Or JavaScriptSerializer
Dim json = New JavaScriptSerializer().Serialize(myobj)
► The original code has more than one issue:
webRequest.ContentLength
is set too late: it needs to be set before the request sentContent-Type
cannot be set using the Headers, we must use WebRequest.ContentType
propertySecurityProtocolType.Tls12
in case this code is used in Windows 7 or a WM (in Windows 7, the default is SecurityProtocolType.Ssl3 Or SecurityProtocolType.Tls
, thus TLS1.0, which isn't really used anymore, TLS1.2 is (still) the major player at this time)Fixed original code, using JavaScriptSerializer
to serialize the request data:
Replace Imports System.Web.Script.Serialization
with Imports Newtonsoft.Json
if you use Json.Net.
Imports System.IO
Imports System.Text
Imports System.Web.Script.Serialization
Dim myobj = New MyObject() With {
.Coordinates = New List(Of List(Of Double)) From {
New List(Of Double)({8.681495, 49.41461}),
New List(Of Double)({8.686507, 49.41943}),
New List(Of Double)({8.687872, 49.420318})
}
}
Dim json As String = New JavaScriptSerializer().Serialize(myobj)
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim request = WebRequest.CreateHttp("https://api.openrouteservice.org/v2/directions/driving-car/gpx")
request.Method = "POST"
request.PreAuthenticate = True
request.Accept = "application/json, application/geo+json, application/gpx+xml, img/png; charset=utf-8"
request.Headers.Add("Authorization", "[Your API Key]")
request.ContentType = "application/json; charset=utf-8"
Dim jsonBytes = Encoding.UTF8.GetBytes(json)
request.ContentLength = jsonBytes.Length
Using reqStream = request.GetRequestStream()
reqStream.Write(jsonBytes, 0, jsonBytes.Length)
End Using
Dim responseContent As String = String.Empty
Using response = DirectCast(request.GetResponse(), HttpWebResponse),
responseStream = response.GetResponseStream(),
reader = New StreamReader(responseStream)
responseContent = reader.ReadToEnd()
End Using
Upvotes: 2