WCF REST Service call - 400 bad request - vb.net

I am struggling to resolve this issue, pls help. I have to call REST WCF service to pass an object.
Can you tell me a code to see xml format that I am trying to send to service.
Dim request As WebRequest
request = WebRequest.Create("http://localhost:1143/ServiceHost.svc/REST/GetResponseCode")
request.Method = "POST"
request.ContentType = "application/xml; charset=utf-8"
Dim dcs As New DataContractSerializer(GetType(transaction))
Dim xdw As XmlDictionaryWriter = _
XmlDictionaryWriter.CreateTextWriter(request.GetRequestStream(), Encoding.UTF8)
dcs.WriteObject(xdw, tran)
Dim res As WebResponse = request.GetResponse()

Well. At last found solution. It's a bug in my code and there are no issues with messaging transport. Mistakenly, I have passed Class as a parameter in GetType in above code.
Dim dcs As New DataContractSerializer(tran.GetType())
Also I have closed XmlDictionaryWriter at the end, otherwise 'Request.GetResponse()' timeout will happens.

Related

Why would my VB.NET WebRequest suddenly stop working?

A while ago I wrote a programme in VB.NET to use the Betfair Exchange API. It has worked perfectly for months, but overnight on Tuesday it stopped working. I can still log in, but from Wednesday I have been unable to get anything else from the server.
Betfair are investigating, but according to them nobody else seems to be experiencing the same problem - although I'm not sure how many will be using VB.NET.
Below is the function I have been using to obtain data from the API. Like I said it was working on Tuesday night but not from Wednesday morning. Is there anything here which is "not perfect" or "could be better", or perhaps there is some alternative code I could try? Or is there something which might have happened on my pc which has caused the problem?
The programme falls over at the line "dataStream = request.GetRequestStream() ". The error is "Received an unexpected EOF or 0 bytes from the transport stream."
I would be grateful for any advice that anyone could offer. Thank you!
Public Function CreateRequest(ByVal postData As String, Optional ByVal accountsApi As Boolean = False)
Dim Url As String = "https://api.betfair.com/exchange/betting/json-rpc/v1"
If accountsApi Then Url = "https://api.betfair.com/exchange/account/json-rpc/v1"
Dim request As WebRequest = Nothing
Dim dataStream As Stream = Nothing
Dim response As WebResponse = Nothing
Dim strResponseStatus As String = ""
Dim reader As StreamReader = Nothing
Dim responseFromServer As String = ""
Try
request = WebRequest.Create(New Uri(Url))
request.Method = "POST"
request.ContentType = "application/json-rpc"
request.Headers.Add(HttpRequestHeader.AcceptCharset, "ISO-8859-1,utf-8")
request.Headers.Add("X-Application", appKey)
request.Headers.Add("X-Authentication", sessToken)
Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData) ' Data to post such as ListEvents, ListMarketCatalogue etc
request.ContentLength = byteArray.Length ' Set the ContentLength property of the WebRequest.
dataStream = request.GetRequestStream() ' Get the request stream.
dataStream.Write(byteArray, 0, byteArray.Length) ' Write the data to the request stream.
dataStream.Close() ' Close the Stream object.
response = request.GetResponse() ' Get the response.
strResponseStatus = CType(response, HttpWebResponse).StatusDescription ' Display the status below if required
dataStream = response.GetResponseStream() ' Get the stream containing content returned by the server.
reader = New StreamReader(dataStream) ' Open the stream using a StreamReader for easy access.
responseFromServer = reader.ReadToEnd() ' Read the content.
reader.Close() : dataStream.Close() : response.Close()
Catch ex As Exception
MsgBox("CreateRequest Error" & vbCrLf & ex.Message, MsgBoxStyle.Critical, " Error")
End Try
Return responseFromServer
End Function
I would check that the provider hasn't recently deprecated use of TLS 1.0 (as they should have done before now, in fact).
If so, your code needs to enforce use of TLS 1.1+:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;
This only has to be set once, usually in the (static) type initializer or similar.
And I 100% agree with Andrew Mortimer that you should use Using blocks wherever possible. I'd also suggest moving all of your string values into variables or constants to clean things up and keep them maintainable. Eg:
Const ContentType As String = "application/json-rpc"
...
request.ContentType = ContentType
UPDATE
I just found this announcement on their site:
https://forum.developer.betfair.com/forum/developer-program/announcements/33563-tls-1-0-no-longer-supported-from-1st-december-all-betfair-api-endpoints
If you are allowed to use external dependencies within this project I would recommend using RestSharp nuget package it works really well for creating API requests and getting there response without having to use httpclient which gets messy.
Link: https://restsharp.dev/

Problem query get to api rest with authorization bearer

I need to make a query by getting to an api rest with authorization bearer, the problem is that the vb.net code returns an error in the GetResponse.
ERRORS:
The connection is terminated: Unexpected shipping error.
IOException: Unable to write data to the transport connection: The interruption of an existing connection has been forced by the remote host.
SocketException: The interruption of an existing connection has been forced by the remote host**
I'm not sure the code is correct since I have not found very good examples on the internet ...
I would appreciate the help of someone who understands a bit more than me about the topic
Thanks for all!
Dim s As HttpWebRequest
Dim r As HttpWebResponse
Dim reader As StreamReader
s = HttpWebRequest.Create("https://xxxx.xxxx.net/api/v1/PrivilegedCustomers/byIdentity/D/04400012680")
s.Method = "GET"
s.Headers.Add("Authorization", "Bearer " & Token())
's.ContentType = "application/x-www-form-urlencoded"
r = DirectCast(s.GetResponse(), HttpWebResponse)
reader = New StreamReader(r.GetResponseStream())
Dim json_api As String = reader.ReadToEnd()
Dim json As JObject = JObject.Parse(json_api)

Can't make BigCommerce API call in VB.NET

I get
'underlying connection was closed'
when running the code below. I am using vb.net 2012 (I must use this version) with the RestSharp library and am trying to retrieve product data from a bigcommerce.com store. This is a simple vb.net 2012 console program that once I get working I can build upon. I have tried changing around the code somewhat even making certain things redundant like the method and URL but I can't get it to work.
Dim client As New RestClient
client.BaseUrl = New Uri("https://api.bigcommerce.com/stores/mystorehash/v3/catalog/products")
Dim request As New RestRequest("https://api.bigcommerce.com/stores/mystorehash/v3/catalog/products", Method.GET)
request.AddHeader("Accept", "application/json")
request.AddHeader("Content-Type", "application/json")
request.AddHeader("X-Auth-Client", "notactualvaluenotactualvalue")
request.AddHeader("X-Auth-Token", "notactualvaluenotactualvalue")
request.Method = Method.GET
Dim response As New RestResponse
response = client.ExecuteAsGet(request, Method.GET)
Console.WriteLine("response.Content=" & response.Content)
Console.WriteLine("response.ErrorMessage=" & response.ErrorMessage)
Console.WriteLine("response.ResponseStatus=" & response.ResponseStatus)
Console.WriteLine("response.IsSuccessful=" & response.IsSuccessful)
Console.WriteLine("response.Headers.Count=" & response.Headers.Count)
Output:
Any help would be appreciated, hopefully I'm doing something stupid that can be easily fixed
For anyone else that finds this the full implementation of Nathan Booker's suggestion is below. When you attempt to access the Big Commerce api in a VB.NET application you need to specify TLS 1.2. If you don't you'll recieve an HTTP status of 502 - System.IO.IOException Authentication failed because the remote party has closed the transport stream. The solve is done like:
ServicePointManager.Expect100Continue = True
ServicePointManager.SecurityProtocol = CType(3072, SecurityProtocolType)
ServicePointManager.DefaultConnectionLimit = 9999
Dim request As HttpWebRequest = CType(WebRequest.Create("https://api.bigcommerce.com/stores/<Redacted>/v3/catalog/products"), HttpWebRequest)
request.AllowAutoRedirect = True
request.ContentType = "application/json"
request.Accept = "application/json"
request.Method = "GET"
request.Headers.Add("X-Auth-Client", "<Redacted>")
request.Headers.Add("X-Auth-Token", "<Redacted>")
Dim response As WebResponse = request.GetResponse()
Diagnostics.Debug.WriteLine((CType(response, HttpWebResponse)).StatusDescription)
Dim dataStream As Stream = response.GetResponseStream()
Dim reader As StreamReader = New StreamReader(dataStream)
Dim responseFromServer As String = reader.ReadToEnd()
Diagnostics.Debug.WriteLine(responseFromServer)
reader.Close()
response.Close()
This may be related to your HTTP version or (more likely) SSL/TLS protocol.
If possible, please make sure you're using HTTP 1.1 and TLS 1.2.

Trouble with POSTing JSON to endpoint

I'm trying to submit a POST request containing JSON to a given endpoint. However the below code sends me to a login page which is the default functionality for all non-/api endpoints. Because Postman doesn't direct me to the login page but correctly hits the API, I'm assuming the problem is in this C# code.
Dim RemoteUrl As String = "https://my-site.com/api/tournament/results"
Dim result As String = ""
Dim xmlHttpReq As HttpWebRequest = CType(WebRequest.Create(RemoteUrl), HttpWebRequest)
xmlHttpReq.Method = "POST"
xmlHttpReq.ContentType = "application/json"
With (New StreamWriter(xmlHttpReq.GetRequestStream))
.Write(Json)
.Flush()
.Close()
Dim httpResponse As HttpWebResponse = CType(xmlHttpReq.GetResponse(), HttpWebResponse)
With (New StreamReader(httpResponse.GetResponseStream))
result = .ReadToEnd
End With
End With
Any idea what steps I need to take to debug this?

How to call a WebAPI2 from VB.NET

I'm trying to call a WebAPI2 api from a legacy VB code.
The API works when called from fiddler or from the AngularJS client.
[Route("CreateMyObject")]
[HttpPost]
public async Task<JsonResult<MyObject>> CreateMyObject([FromUri] int parentId, [FromBody] MyObject object)
Then in the VB code:
Dim apiUri As New Uri(apiUrl & "api/CreateMyObject?parentId=" &
intParentId.ToString())
Dim data = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(myObjectInstance))
Dim webRequest As WebRequest = WebRequest.Create(uri)
webRequest.ContentType = "application/json"
webRequest.Method = "POST"
webRequest.ContentLength = data.Length
Dim stream = webRequest.GetRequestStream()
stream.Write(data, 0, data.Length)
stream.Close()
Dim response = webRequest.GetResponse().GetResponseStream()
Dim reader As New StreamReader(response)
Dim res = reader.ReadToEnd()
reader.Close()
response.Close()
I can only get a 415 response from the API. I tried other content-types as well, but with the same result or server error.
Whatever is wrong with this call seems to be related with the Json body bit, because if I don't send anything in the call body, the parentId gets to the API as it's supposed to.
As Chase Rocker mentioned, try first by initializing jsonDataBytes as
Dim jsonDataBytes As Bytes()
Also verify the json object to make sure it is fine. Use this link http://jsonlint.com/ or for better assistance use Fiddler
instead.