REST call in vb.net: how to transfer a key file that works in cURL

I tried this problem for almost a month, and I read everything I could find on the Internet, without a solution. Here is my problem: I am implementing a client for the RESTful API service, which should send an XML file via a POST call to vb.net. I can make it work when it comes to receiving data in xml format, but when it comes to sending this Xml file, I always get the "400 errors" error.

I already realized that this should be a key issue that should be sent to the server (which, apparently, only accepts file uploads for POST, I cannot send it as a string).

Basically, this call works with cURL, but I am struggling to implement my own call in vb.net, passing the correct value.

CURL working call: (which successfully passes XML)

c:>curl -u username:password -F " file=@filename.xml " -X POST http://hostname.com/URI?parameters 

Vb.net code does not work: (this gives me 400 Bad Request)

 Dim ss As String = "" 'server says... Dim S As String = txb_username.Text & ":" & txb_password.Text Dim EncodedString As String = System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(S)) Dim req As HttpWebRequest = Nothing Dim res As HttpWebResponse = Nothing Try Dim xmlDoc As System.Xml.XmlDocument = New System.Xml.XmlDocument xmlDoc.XmlResolver = Nothing xmlDoc.Load("c:\path\file4.xml") Dim sXML As String = "file" & xmlDoc.InnerXml '<- This is where I try to put the "KEY" Dim url As String = "http:/host.com+URI" req = CType(WebRequest.Create(url), Net.HttpWebRequest) 'or Directcast ... req.Method = "POST" req.Headers.Add("Authorization: Basic " & EncodedString) req.ContentType = "multipart/form-data" req.ContentLength = sXML.Length req.Accept = "*/*" System.Windows.Forms.Application.DoEvents() Dim sw As System.IO.StreamWriter = New System.IO.StreamWriter(req.GetRequestStream) StatusUpdate(sXML) sw.Write(sXML) sw.Close() ss = "server says: " res = CType(req.GetResponse, HttpWebResponse) StatusUpdate(req.ToString) Catch ex As Exception StatusUpdate(ss & ex.Message) Finally End Try 

Is it because I'm trying to send it as a string? (but how else can I send it as a file?) For this, I did another procedure that sends data bytes, but it also gives me β€œ400”, because (I suppose) I did not put the key β€œfile”.

  Dim requestStream As Stream = Nothing Dim fileStream As FileStream = Nothing Dim uploadResponse As Net.HttpWebResponse = Nothing Try Dim uploadRequest As Net.HttpWebRequest = CType(Net.HttpWebRequest.Create(URI.Text & Uri_part2.text), Net.HttpWebRequest) uploadRequest.Method = Net.WebRequestMethods.Http.Post uploadRequest.ContentType = "text/xml; charset=utf-8" uploadRequest.Credentials = New NetworkCredential("user", "pass") uploadRequest.KeepAlive = True uploadRequest.UserAgent = "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10" uploadRequest.Accept = ("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8") uploadRequest.Headers.Add("Accept-Language: en-us,en;q=0.5") uploadRequest.Headers.Add("Accept-Encoding: gzip,deflate") uploadRequest.Headers.Add("Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7") uploadRequest.Headers.Add("Content-Disposition: form-data; name=""file"";") uploadRequest.ContentType = "application/xml; charset=utf-8" requestStream = uploadRequest.GetRequestStream() fileStream = File.Open("C:\example.xml", FileMode.Open) Dim a As Integer Dim buffer(1024) As Byte Dim bytesRead As Integer While True a = a + 1 bytesRead = fileStream.Read(buffer, 0, buffer.Length) StatusUpdate(buffer(a)) If bytesRead = 0 Then Exit While End If requestStream.Write(buffer, 0, bytesRead) End While requestStream.Close() uploadResponse = uploadRequest.GetResponse() Dim responseReader As StreamReader = New StreamReader(uploadRequest.GetResponse.GetResponseStream()) Dim x As String = responseReader.ReadToEnd() responseReader.Close() StatusUpdate(x) Catch ex As UriFormatException StatusUpdate("UriFormatException: " & ex.Message) Catch ex As IOException StatusUpdate("IOException: " & ex.Message) Catch ex As Net.WebException StatusUpdate("Net.WebException: " & ex.Message) Finally If uploadResponse IsNot Nothing Then uploadResponse.Close() End If If fileStream IsNot Nothing Then fileStream.Close() End If If requestStream IsNot Nothing Then requestStream.Close() End If End Try 

In any case, I tried the other 2 clients (POSTMAN and REST Console, 2 extensions for Google Chrome), and I can make it work only if I add the value "file" to the "key" field. I have to insert a specific 4-character "file" to make it work. So the question is: how to add the same value in a Vb.net call? How can I translate the cURL call code into Vb.net working code? Thank you so much for your time and help !!!

find the image of the thing i want to add here, wanted image

PS I can’t use PUT, I have to use POST (server restriction)

I also add HTML code that works for my purpose, with the server from my computer (again, see the "file")

 <html> <body> <form enctype="multipart/form-data" action="http://URI" method="POST"> <table border=0> <tr> <td align="right">File&nbsp;</td> <td><input type="FILE" name="file"></td> </tr> <tr> <td>&nbsp;</td> <td><input type="submit"></td> </tr> </table> </form> </body> </html> 

I also embed the script in PERL, which also works with the server from my computer.

  #!perl use strict; use LWP; # Loads all important LWP classes my $client_id = 1234; my $filename = "new_file.xml"; ### Prepare to make a request my $browser = LWP::UserAgent->new; my $url = "http://uri.com?&xx=$client_id"; my @post_pairs = ( #'client_id_in' => $client_id, 'file' => [$filename], ); my @ns_headers = ( 'User-Agent' => 'Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10', 'Accept' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language' => 'en-us,en;q=0.5', 'Accept-Encoding' => 'gzip,deflate', 'Accept-Charset' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', 'Authorization' => 'Basic base64EncodedCredentialsHere', 'Content_Type' => 'form-data', ); ### Make a request my $response = $browser->post($url, \@post_pairs, @ns_headers); die "Can't get $url -- ", $response->status_line unless $response->is_success; ### Display the response print STDOUT $response->content; 
+4
source share
1 answer

I think your problem is that you really do not know what the request should look like, please use a violinist to look at the request sent by cURL and try to implement the same with vb.net. In my opinion, your secons code fragment (with a buffer, not with xml serializers) should work ... but only if this structure can be understood on the server side.

+1
source

Source: https://habr.com/ru/post/1435297/


All Articles