Adding Header to Web Request throws an error - vb.net

When attempting to add a value to the header of an HTTP request, I get the following error:
Specified value does not have a ':' separator. Parameter name: header
To add the header I am using the following code:
Dim request As HttpWebRequest = WebRequest.Create(url)
Dim soapXML As New XmlDocument()
soapXML.LoadXml(soapEnvelope)
request.Headers.Add("SOAPAction", action)
request.Method = "POST"
request.ContentType = "text/xml;charset=""utf-8"""
request.Accept = "text/xml"
Using stream As Stream = request.GetRequestStream()
soapXML.Save(stream)
End Using
I have been looking all over the place and haven't found anybody who has had any similar errors, outside of this SO question: using httpRequest headers?
Which didn't help much.
Does anybody know what I might be doing wrong here?
EDIT 1: Added all the code that I currently have that creates my web request.

Related

How to corectly set the ContentType property in HttpWebRequest (or how to fix the missing Content-Type header)

I thought I'd share something that took me some time to figure out:
I wrote a simple Post method using HttpWebRequest class.
In HttpWebRequest you can't use HttpWebRequest.Headers collection to set your desired headers when there is a dedicated property for it - you must use that dedicated property. ContentType is one of them. So I created my HttpWebRequest like this:
HttpWebRequest httpWebRequest = (HttpWebRequest)webRequest;
httpWebRequest.Method = "POST";
httpWebRequest.KeepAlive = false;
httpWebRequest.ServicePoint.Expect100Continue = false;
httpWebRequest.ContentType = "application/json";
somewhere below I set the body of my request like this:
using (StreamWriter streamWriter = new StreamWriter(streamWebRequest))
{
streamWriter.Write(sJson);
}
and posted the request using:
WebResponse webResponse = httpWebRequest.GetResponse();
But I kept getting a "400 - Bad Request" error, while the same request worked from Postman. After analyzing the request with Fiddler I found that when I send the request from my app, the Content-Type: application/json header is missing. All the other headers were present, except for Content-Type. I thought I'm setting it wrong, so I googled but didn't find a good answer. After much experimentation I found, that if I move the line:
httpWebRequest.ContentType = "application/json"
after this block:
using (StreamWriter streamWriter = new StreamWriter(streamWebRequest))
{
streamWriter.Write(sJson);
}
then the httpWebRequest.ContentType = "application/json" header finally appears in the request. So, for HttpWebRequest make sure you always set your HttpWebRequest's body/content first, before you set the ContentType property.
Hope it helps
My question above already has the answer, but to mark it as "Answered" I had to add this comment:
Make sure you always set your HttpWebRequest's body/content first, before you set the ContentType property.This way the "Content-Type" header will appear in the request.

Unexpected error occurred on a receive using API on my Wix site

I've made an experimental email and password system using post requests to my Wix site API and I've verified it works through curl and postman. When trying to use it in my VB.NET app however I get the error: "The underlying connection was closed: An unexpected error occurred on a receive." I already previously ran into a "Could not create SSL/TLS secure channel" error but that was resolved when I moved the .NET framework for the project to 4.7.1 and made sure SecurityProtocol was set to SystemDefault as Wix seems to use TLS 1.3. Now however I'm getting this error on receive that I have no idea how to resolve as everything in the request seems to look ok:
ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault
Dim req As HttpWebRequest = DirectCast(WebRequest.Create(New Uri("https://xxxxx.com/mysite/_functions/check?email=" & email & "&pass=" & LCase(passHash))), HttpWebRequest)
req.Method = "POST"
req.ContentType = "none"
req.ContentLength = 0
req.Host = "test"
req.KeepAlive = True
Dim result As HttpWebResponse = req.GetResponse()
The error is thrown when running 'req.GetReponse()'.
After looking at countless versions of sample code for .NET POST requests and questions about this error but everyone seems to suggest setting the security prococol type, which I have done and setting it as the system default is the only way I don't get an internal server error status. Another was setting KeepAlive to false, which I have also tried but didn't make any difference.
What could be the problem here? Here is what's included in the postman header if this is of help:
Ok so eventually I ended up changing my code to use GetResponseAsync() instead of GetResponse() (not that it made any difference to the problem) and set the protocol type back to Tls12 on .NET 4.8. In the end it seemed that having req.Host set was what was causing the issue with the response, Wix doesn't seem to like it. I also added some extra settings to the request but ultimately they make no difference to the response. Here is the final working code:
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12
Dim req As HttpWebRequest = WebRequest.CreateHttp("https://example.com/check?email=" & email & "&pass=" & LCase(passHash))
req.Method = "POST"
req.ContentType = "none"
req.ContentLength = 0
req.KeepAlive = True
req.CookieContainer = New CookieContainer()
req.UserAgent = "Test"
req.Accept = "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
req.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US;q=0.9,en;q=0.5")
req.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8")
req.Headers.Add(HttpRequestHeader.CacheControl, "no-cache")
Dim statusCode As HttpStatusCode = Nothing
Try
Using result As HttpWebResponse = CType(Await req.GetResponseAsync(), HttpWebResponse)
statusCode = result.StatusCode
End Using
If statusCode = HttpStatusCode.OK Then
MsgBox("Valid")
Else
Dim response As String = New StreamReader(req.GetResponse().GetResponseStream()).ReadToEnd()
MsgBox(response)
End If
Catch webEx As WebException
MsgBox(New StreamReader(webEx.Response.GetResponseStream()).ReadToEnd())
End Try

404 error while getting server response vb.net

I'm a totally beginner with webrequest, so I have no idea about what cause the error I get.
I try to login on a form following the microsoft tutorial for webrequest, but when I want to get the server response, I have the following error :
"the remote server returned an error (404) not found"
So I know that the URL I use actually exist and then wonder which part of the code is bad. Maybe it's because I'm doing an HTTPS request unlike the tutorial and it changes something ?
Also, I'm a little confused by getting directly the answer from the server : shouldn't there be kind of a trigger to know when the server answered ?
Dim request = WebRequest.Create("https://ssl.vocabell.com/mytica2/login")
request.Credentials = CredentialCache.DefaultCredentials
request.Method = "POST"
Dim byteArray = Encoding.UTF8.GetBytes("_username=x&_password=x")
request.ContentType = "application/x-www-form-urlencoded"
request.ContentLength = byteArray.Length
Dim dataStream = request.GetRequestStream()
dataStream.Write(byteArray, 0, byteArray.Length)
dataStream.Close()
Dim reponse = request.GetResponse() 'ERROR
MsgBox(CType(reponse, HttpWebResponse).StatusDescription)
Using ds = reponse.GetResponseStream
Dim reader = New StreamReader(ds)
MsgBox(reader.ReadToEnd)
End Using
reponse.Close()
Thank you for your time, and if you have any relevant tutorial on the topic I would be glad to read it !
The page you've mentioned does exist and uses HTTPS, but if you look at the form tag within it, it's like this:
<form class="login-form form-horizontal" action="/mytica2/login_check" method="POST">
This means it doesn't post the form back to the same URL as the page, instead it sends it to the URL contained within that "action" attribute. If you're trying to use your code to simulate the submission of the login form then it looks like you need to send your POST request to https://ssl.vocabell.com/mytica2/login_check instead.

how to add 'Content-Type' header in (HTTP GET) Rest request header collection using HttpClient?

I am using HttpClient for rest service . At at one point I have a problem when I try to add "Content-Type" in my 'Get' request header .
I know "Content-Type" is suitable for content send in request body part But It's my need i have to send "Content-Type" with request header part.
I also try to remove "Content-Type" header from Invalid Header list of HttpRequestHeaders
I find link How do you set the Content-Type header for an HttpClient request?
Dim field = GetType(System.Net.Http.Headers.HttpRequestHeaders).GetField("invalidHeaders", System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.[Static])
If field IsNot Nothing Then
Dim invalidFields = DirectCast(field.GetValue(Nothing), HashSet(Of String))
invalidFields.Remove("Content-Type")
End If
But my issue not resolved I have exception
InnerException:
Message=The 'content-type' header must be modified using the appropriate property or method.
StackTrace:
at System.Net.WebHeaderCollection.ThrowOnRestrictedHeader(String headerName)
at System.Net.WebHeaderCollection.Add(String name, String value)
at System.Net.Http.HttpClientHandler.SetRequestHeaders(HttpWebRequest webRequest, HttpRequestMessage request)
at System.Net.Http.HttpClientHandler.CreateAndPrepareWebRequest(HttpRequestMessage request)
at System.Net.Http.HttpClientHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
InnerException:
I find some tools like Postman or SoupUI allow this .
Please help me to find some solution .
Thanks
HttpWebRequest may come to your rescue.
private static string CallService(string url)
{
WebRequest req = WebRequest.Create(url);
req.Method = "GET";
String json;
req.ContentType = "application/json; charset=utf-8";
var resp = req.GetResponse();
using (varstream = resp.GetResponseStream())
{
var re = new StreamReader(stream);
json = re.ReadToEnd();
}
return json;
}
}
Async implementation of this can be found from Getting the Response of a Asynchronous HttpWebRequest

Square API with Vb.net

Dim myUri = New Uri("https://squareup.com/v2/locations")
Dim RQ As HttpWebRequest = TryCast(WebRequest.Create(myUri), HttpWebRequest)
RQ.PreAuthenticate = True
RQ.Headers.Add("Authorization", "Bearer" & Token) '''Token is a Shared string assigned to my current Access Token
RQ.Method = "GET"
RQ.Accept = "application/json"
RQ.ContentType = "application/json"
Using response As HttpWebResponse = TryCast(RQ.GetResponse(), HttpWebResponse) '''''"The remote server returned an error: (404) Not Found."
Very new to the Square-Connect API and there are no vb.net examples so this was as far as i can get. Im not able to get pass the last line. I always get a 404 error no matter what i try. Anyone know why.
If I use this command (replacing Token with my access Token), in a terminal then I get the result I want in vb.net.
curl -H "Authorization: Bearer Token" https://connect.squareup.com/v2/locations
The guys at square quickly found my problem so here is the working code:
Dim myUri = New Uri("https://connect.squareup.com/v2/locations")
Dim RQ As HttpWebRequest = TryCast(WebRequest.Create(myUri), HttpWebRequest)
RQ.PreAuthenticate = True
RQ.Headers.Add("Authorization", "Bearer " + Token) 'Token is a Shared string assigned to my current Access Token
RQ.Method = "GET"
RQ.Accept = "application/json"
RQ.ContentType = "application/json"
Using response As HttpWebResponse = TryCast(RQ.GetResponse(), HttpWebResponse)