VB.NET POST multiple files and parameters - vb.net

I need to make a POST request to a server.
this request must have multiple parameters, like this :
name
number
host
and multiples files
file1
file2
file3
How can I do that in VB.NET. I tried WebRequest object, but there's no simple way to do that.
thanks

Use Webclient instead :
For values :
' Create a value collection
Dim myNameValueCollection As New NameValueCollection()
' Set up POST variables
myNameValueCollection.Add("name", someName)
myNameValueCollection.Add("number", someNumber)
...
Using wc As New System.Net.WebClient()
wc.UploadValues(remoteUrl, myNameValueCollection)
End Using
And for files simply :
Using wc As New System.Net.WebClient()
wc.UploadFile(remoteUrl, yourfile)
End Using

I didn't check if it will work, but I would try something like:
' post request with some parameters inside query string
uriPath = String.Format("{0}{1}?func=xxx&uid={2}", url, fileName, id)
reqUri = New Uri(uriPath)
webReq = CType(WebRequest.Create(reqUri), HttpWebRequest)
webReq.Method = "Post"
' webReq.Timeout = 10000
webReq.KeepAlive = False
webReq.ContentType = "application/x-www-form-urlencoded"
' HERE is a place to attach your files
' try to run it at loop for each file
form = "name=" & fileName
webReq.ContentLength = form.Length
Dim sw As New StreamWriter(webReq.GetRequestStream, System.Text.Encoding.ASCII)
sw.Write(form)
' here write/send the file content
sw.Flush()
sw.Close()
sw.Dispose()
' reading response
Using res As WebResponse = webReq.GetResponse
Dim st As Stream = res.GetResponseStream()
Dim rd As New StreamReader(st)
status = rd.ReadLine()
If I remember well POST request of application/x-www-form-urlencoded type is sent
in form of:
--- params separator
name=fileName
file content
--- params separator
name=fileName1
file1 content

Related

How to create Http request with header and body format x-www-form-urlencoded and get the cookies value in vb.NET

I'm trying to make an http request with the following attributes
Header - contains a key 'Referer' with a set value
Body format is x-www-form-urlencoded
Body contains multiple keyes 'type', 'encpwd', 'user', 'pwd' & 'admsid'
In the response from the request, I need to obtain values in the cookies. I'm able to do it via Postman get the cookies, however I need to write a function/method to achieve this and return the cookies values which will be required to authenticate in future API calls.
From the internet, I found a sample code as below
Dim client As RestSharp.RestClient = New RestSharp.RestClient(inEndpoint)
client.Timeout = 10000
client.CookieContainer = New System.Net.CookieContainer
Dim request As RestSharp.RestRequest = New RestRequest(RestSharp.Method.Post)
request.AddHeader("Referer", strReferer)
Dim response As IRestResponse = client.Execute(request)
responsecode=response.StatusCode
responsecontent=response.Content
Dim cookies =client.CookieContainer.GetCookieHeader(response.ResponseUri)
cookiecontainer=cookies.ToString
Console.WriteLine("cookieJar "+ cookies.ToString)
Console.WriteLine("response Uri "+response.ResponseUri.ToString)
But when I'm trying this code in Visual Studio (I have installed RestSharp package already), I'm getting lots of error as below:
client.Timeout = 10000 -- Timeout is not a member of RestClient
client.CookieContainer = New System.Net.CookieContainer -- Property 'CookieContainer' is 'Read-Only'
Dim request As RestSharp.RestRequest = New RestRequest(RestSharp.Method.Post) -- Type 'RestRequest' is not defined
request.AddHeader("Referer", strReferer) -- 'AddHeader' is not a member of 'RestRequest'
Dim response As IRestResponse = client.Execute(request) -- Type 'IRestResponse' is not defined
I'm quite new to https request, please help me where I'm making mistake. Also I don't know/find how to add the body parameters with x-www-form-urlencoded format, everywhere it's mentioned in JSON, but this API service only accepts this format for Body.
Thanks for the help in advance.
I've tried the below code
Dim client As RestClient = New RestClient(endPoint)
Dim request As RestRequest = New RestRequest(Method.Post)
request.AddHeader("Referer", strReferer)
request.AddParameter("application/x-www-form-urlencoded", "type=" + strType + "&encpwd= " + strEncPwd + "&user=" + strUser + "&pwd=" + strPwd + "&admsid=" + stradmsID, ParameterType.RequestBody)
Dim response = client.Execute(request)
It generates exception "cannot send a content-body with this verb-type."
Please help
The below code ran successfully.
Dim client = New RestClient(endPoint)
Dim request = New RestRequest()
request.Method = Method.Post
request.AddHeader("Referer", strReferer)
request.AddHeader("Content-Type", "application/x-www-form-urlencoded")
request.AddParameter("type", strType)
request.AddParameter("encpwd", strEncPwd)
request.AddParameter("user", strUser)
request.AddParameter("pwd", strPwd)
request.AddParameter("admsid", stradmsID)
Dim response = client.Execute(request)
Dim cookies = client.CookieContainer.GetCookieHeader(response.ResponseUri)
Console.WriteLine("cookieJar " + cookies.ToString)
Console.WriteLine(response.Content)
Hope it will help someone. Thanks

Upload a file to SharePoint using REST API and vb.net

I have a project to upload files to Sharepoint using REST API ( POST).
I am using vb.net and RestSharp. Code is below. this code is working.
I am able to do with the small Text file only and the file is getting properly upload into Sharepoint. But when it comes to another file format ( XLS, XLSX, PDF, JOG, Doc ..etc) with a file size greater than 1 MB file is getting uploaded with it, not in a readable format. I tried to upload a ZIP file for 55 MB it is getting Uploaded. But When I download the same uploaded file I am not able to read it.
Can anyone please help me, to get this fixed?
** I would need a solution to upload any file format for any size ( In my project I will not use any file more than 500 MB for upload. )
Below is the code is tried.
Public Sub UploadFile2()
Dim FullfileName As String = "E:\Desktop\try\FileToUpload.xlsx"
Dim NewFileName As String = "NewFile.xlsx"
Dim uploadFileUrl As String = SiteUrl + "_api/web/lists/getByTitle('Documents')/RootFolder/Files/Add(url='" + NewFileName + "', overwrite=true)"
Dim client = New RestClient(uploadFileUrl) With {
.Timeout = -1
}
Dim UploadRequest = New RestRequest(Method.POST)
UploadRequest.AddHeader("Accept", "application/json;odata=verbose")
UploadRequest.AddHeader("X-RequestDigest", DigestValue)
UploadRequest.AddHeader("Authorization", "Bearer " + AccessToken)
UploadRequest.AddHeader("Content-Type", "multipart/form-data")
UploadRequest.AlwaysMultipartFormData = True
UploadRequest.AddFile("FileName", FullfileName)
UploadResponse = client.Execute(UploadRequest)
End Sub
Looks like you need to pass the Content-Length header.
For anyone interested, this worked for me:
Public Sub UploadFile2()
Dim FullfileName As String = "E:\Desktop\try\FileToUpload.xlsx"
Dim NewFileName As String = "NewFile.xlsx"
Dim uploadFileUrl As String = SiteUrl + "_api/web/lists/getByTitle('Documents')/RootFolder/Files/Add(url='" + NewFileName + "', overwrite=true)"
Dim client = New RestClient(uploadFileUrl) With {
.Timeout = -1
}
Dim UploadRequest = New RestRequest(Method.POST)
UploadRequest.AddHeader("Accept", "application/json;odata=verbose")
UploadRequest.AddHeader("X-RequestDigest", DigestValue)
UploadRequest.AddHeader("Authorization", "Bearer " + AccessToken)
UploadRequest.AddHeader("Content-Type", "application/octet-stream")
UploadRequest.AddParameter("application/octet-stream", File.ReadAllBytes(FullfileName), ParameterType.RequestBody)
UploadResponse = client.Execute(UploadRequest)
End Sub

VB - save response as binary

Please see part of the code used to save response as a string to resultData variable:
Using response As WebResponse = request.GetResponse()
Dim responseStream As IO.Stream = response.GetResponseStream()
Dim sr As New IO.StreamReader(responseStream)
resultData = sr.ReadToEnd()
It works correctly.
I have one case where the output is a binary file. How can I modify this code to save the reponse as a binary ResultData variable?
Thank you in advance for your support.
There is many ways to do that. This one, is one of those. (This one help you also to show the progress)
However (as advice) to monitoring progress there exists better approaches like Async methods etc.
In the example below I’m going to show you how to save e WebRequest as binary data.
Note that, I’m based on your code and what you want, but, as I said before there exists different better approaches.
'here the file you want to save
Dim LocalFilePath As String = "C:\Users\MyUser\Documents\FolderXYZ\yourfileName.extension"
Using reader As IO.Stream = request.GetResponse.GetResponseStream
Using writer As IO.Stream = New IO.FileStream(LocalFilePath, IO.FileMode.OpenOrCreate, IO.FileAccess.ReadWrite)
Dim b(1024 * 2) As Byte
Dim buffer As Integer = b.Length
Do While buffer <> 0
buffer = reader.Read(b, 0, b.Length)
writer.Write(b, 0, buffer)
writer.Flush()
Loop
End Using
End Using

Identify the file type of a File / Stream - VB.Net

I have a problem when I download a file from a URL (This it's not my main problem), the problem comes after that.
The file that I saved from the URL can be a image, doc, PDF or ZIP.
Exists some method to know the file type when the path doesn't has the extension?
Or identify the file type from an stream?
I'm working with Visual Studio 2010 Express Edition - Framework.Net 3.5 - A Window App
Public Function DownloadFile_FromURL(ByVal URL As String, ByVal DestinationPath As String) As Boolean
DownloadFile_FromURL = False
Try
Dim vRequest As Net.HttpWebRequest
Dim vResponse As Net.HttpWebResponse
vRequest = Net.WebRequest.Create(New Uri(URL))
vRequest.Method = "GET"
vRequest.AllowAutoRedirect = True
vRequest.UseDefaultCredentials = True
vResponse = vRequest.GetResponse
If vResponse.ContentLength <> -1 Then
Dim vLen As Long = vResponse.ContentLength
Dim vWriteStream As New IO.FileStream(DestinationPath, IO.FileMode.CreateNew)
Dim vStream As IO.Stream = vResponse.GetResponseStream()
Dim vReadBytes() As Byte = New Byte(255) {}
Dim vCount As Integer = vStream.Read(vReadBytes, 0, vReadBytes.Length)
While vCount > 0
vWriteStream.Write(vReadBytes, 0, vCount)
vCount = vStream.Read(vReadBytes, 0, vReadBytes.Length)
End While
vWriteStream.Flush() : vWriteStream.Close()
vResponse.Close() : vRequest = Nothing : GCcleaner()
Dim v = System.IO.Path.GetExtension(DestinationPath)
DownloadFile_FromURL = True
End If
Catch ex As Exception
Throw New Exception(ex.mc_GetAllExceptions)
End Try
End Function
If you are using WebRequest for the download.
Dim uri As String = "http://domain.com/resource"
Dim request As HttpWebRequest = DirectCast(WebRequest.Create(uri), HttpWebRequest)
request.Method = "GET"
Dim response As HttpWebResponse = DirectCast(request.GetResponse(), HttpWebResponse)
Dim contentType = response.ContentType
' this will have the content type/ file type
You can now have a routine to save the file using a particular extension depending on the content type. for instance a content type of "image/jpeg" can be saved as *.jpg
For an Image you can load it into an Image() object and see if it throws an OutOfMemoryException -- not an image.
PDF you can read the first few bytes of it (the PDF file type info is stored there, though not sure exactly what it is at the moment).
ZIP and DOC I'm not sure about.
If you are using WebRequests you can grab the content type of the response stream. More information about the MIME/content types here: http://msdn.microsoft.com/en-us/library/ms775147.aspx

Visual Basic set User Agent with ReadXml

I'm trying to set the user agent for a request with XmlRead. I googled a lot about this and couldn't find the answer. Here is my chunk of code:
Dim RssData As DataSet
Dim Title As String
Dim Url As String
Dim Stream As String
Dim buffer As Integer
RssData = New DataSet()
RssData.ReadXml("http://localhost/user_agent.php")
buffer = 0
For Each RssRow As DataRow In RssData.Tables("entry").Rows
Title = Microsoft.VisualBasic.Left(RssRow.Item("title").ToString, 30)
Stream += Title & vbCrLf
Next
LinkLabel3.Text = Stream
For Each RssRow As DataRow In RssData.Tables("entry").Rows
Title = Microsoft.VisualBasic.Left(RssRow.Item("title").ToString, 30)
Url = RssRow.Item("url").ToString
LinkLabel3.Links.Add(buffer, Title.Length, Url)
buffer = buffer + Title.Length + 2
Next
The part of the code that actually performs the web request is buried pretty deep so you'd have to inherit a bunch of code to do what you asked for. Instead, let me suggest a different path, download the XML on your own with code that's easy to set that header, and then load that into the dataset. The WebClient class lets you set arbitrary headers and has a simple DownloadString method. Once you've got that you can wrap it in a MemoryStream and pass that into ReadXml(). (I couldn't find a way to read the XML as a string, that's why I was forced to read it as Stream.)
''//Will hold our downloaded XML
Dim MyXml As String
''//Create a webclient to download our XML
Using WC As New System.Net.WebClient()
''//Manually set the user agent header
WC.Headers.Add("user-agent", "your user agent here")
''//Download the XML
MyXml = WC.DownloadString("http://localhost/user_agent.php")
End Using
''//Create our dataset object
Dim RssData As New DataSet()
''//There is no direct method to load XML as a string (at least that I could find) so we will
''// convert it to a byte array and load it into a memory stream
Dim Bytes As Byte() = System.Text.Encoding.UTF8.GetBytes(MyXml)
Using MS As New System.IO.MemoryStream(Bytes)
''//Load the stream into the reader
RssData.ReadXml(MS)
End Using
''//Your code continues normally here