I am trying to implement the Aramex API for Tracking on my VB.NET website, but I'm getting an error.
Here is my code:
Imports TrackingReference
Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim _Request As New ShipmentTrackingRequest
_Request.ClientInfo = New ClientInfo
_Request.ClientInfo.AccountCountryCode = "JO"
_Request.ClientInfo.AccountEntity = "AMM"
_Request.ClientInfo.AccountNumber = "20016"
_Request.ClientInfo.AccountPin = "331421"
_Request.ClientInfo.UserName = "reem#reem.com"
_Request.ClientInfo.Password = "123456789"
_Request.ClientInfo.Version = "v1.0"
_Request.Transaction = New Transaction
Dim _Shipments As New List(Of String)
_Shipments.Add("7055174991")
_Request.Shipments = _Shipments.ToArray()
_Request.GetLastTrackingUpdateOnly = True
Dim _Client As New Service_1_0Client()
Dim _response As ShipmentTrackingResponse = Nothing
_Client.Open()
_response = _Client.TrackShipments(_Request)
If Not _response Is Nothing Then
For Each _Result As KeyValuePair(Of String, TrackingResult()) In _response.TrackingResults
Dim _trResult() As TrackingResult = _Result.Value
For Each trR In _trResult
Response.Write(trR.UpdateLocation & "<br>")
Next
Next
End If
_Client.Close()
End Sub
End Class
This is my error:
I have found the Aramex Developer community to be full of questions but no answers. How can I fix the problem?
Related
What I'm attempting to do should be SO easy. Here's my question:
Using VB.NET (If you do C# that's cool too.) with the Google Calendar API, upon a simple GetRequest for one event, with four measly lines of code as shown below, why on earth am I getting
Message[Not Found] Location[ - ] Reason[notFound] Domain[global]
Private Function GetEvent(ByVal CalID As String, ByVal EventID As String) As [Event]
Dim service As CalendarService = GetCalendarService()
Dim request As EventsResource.GetRequest = service.Events.Get(CalID, EventID)
Dim ThisEvent As [Event] = request.Execute()
Return ThisEvent
End Function
It seems this should be easy... I can already retrieve a list of all my calendars, lists of events from any calendar, and I can insert events into any calendar. All of that is working great. I almost thought I knew what I was doing, until this cropped up.
Since I think the reader may be inclined to point to scope, proper credentials, or that my EventID and CalendarID don't match up, those aren't it. The EventID and the CalendarID were both obtained from a previous event ListRequest.
I'm aware that I could "cheat" and use an event ListRequest (since I'm doing that successfully) to get just the one event, but that's not the proper way to go about it and I'm pretty sure a GetRequest (using EventID) will be faster. I only want the one event.
Any guidance would be much appreciated.
I have to be honest, I don't know how I solved it. I decided to start a whole new project from scratch to test all of the features of the API I have tried so far:
Getting a list of calendars
Getting Lists of events within calendars
Inserting events
And (what failed before) a get request. ...which now works.
WHY it works and it didn't before, I still have no idea. The problem must be elsewhere in my project where it fails, but I'll find it.
For those who may find it helpful (there are very few VB examples out there), make a new project with Form1, add four buttons, a textbox, and a combobox with their default names.
So here's the code:
Imports System.IO
Imports System.Threading
Imports Google.Apis.Auth.OAuth2
Imports Google.Apis.Calendar.v3
Imports Google.Apis.Calendar.v3.Data
Imports Google.Apis.Services
Imports Google.Apis.Util.Store
Imports System.Windows.Forms
Public Class Form1
Private Shared Scopes() As String = {CalendarService.Scope.CalendarEvents, CalendarService.Scope.CalendarReadonly} ', CalendarService.Scope.Calendar}
'If I ever need to create calendars, or read them
Private objCalendars As Data.CalendarList '///Holds all calendars.
Private selectedCalendarID As String = "" '//Holds the currently selected Calendar ID.
Private Const calendarTimeZone = "America/Los_Angeles"
'Both of these are for testing purposes.
Dim TestEventID As String = ""
Dim TestCalendarID As String = "primary"
Private Function GetCalendarService() As CalendarService
Dim credential As UserCredential
Using stream = New FileStream("credentials.json", FileMode.Open, FileAccess.ReadWrite)
Dim credPath As String = "token.json"
credential = GoogleWebAuthorizationBroker.AuthorizeAsync(GoogleClientSecrets.Load(stream).Secrets, Scopes, "user", CancellationToken.None, New FileDataStore(credPath, True)).Result
End Using
Return New CalendarService(New BaseClientService.Initializer() With {.HttpClientInitializer = credential})
End Function
Private Sub LoadCalendars()
Dim service As CalendarService = GetCalendarService()
Dim objCalendarListRequest As CalendarListResource.ListRequest = service.CalendarList.List
objCalendars = objCalendarListRequest.Execute()
If objCalendars Is Nothing Or objCalendars.Items.Count = 0 Then
'** No calendars. Something is wrong. Give up and die.
MsgBox("No calendars found? That's weird.")
End
Else
ComboBox1.Items.Clear()
ComboBox1.Items.Add("primary")
For Each objCal As Data.CalendarListEntry In objCalendars.Items
Console.WriteLine(objCal.Summary)
ComboBox1.Items.Add(objCal.Summary)
Next
ComboBox1.SelectedIndex = 0
End If
End Sub
Private Function GetCalendarIDFromSummary(ByVal Summary) As String
If Summary = "primary" Then Return Summary
If objCalendars IsNot Nothing AndAlso objCalendars.Items.Count > 0 Then
For Each objCal As Data.CalendarListEntry In objCalendars.Items
If objCal.Summary = Summary Then
Return objCal.Id
End If
Next
End If
Return "" 'Should have found a match if objCalendars was properly loaded.
End Function
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
Call LoadCalendars()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim summary As String = "Hello World"
If Trim(TextBox1.Text) <> "" Then summary = Trim(TextBox1.Text)
Call InsertEvent(summary, "1600 Pennsylvania Avenue NW, Washington, DC 20500", "My Description of this event.", Now, 60, GetCalendarIDFromSummary(ComboBox1.SelectedItem.ToString))
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
If TestEventID <> "" Then
MsgBox(GetEvent(TestCalendarID, TestEventID).Summary)
End If
End Sub
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Call SearchEvents()
End Sub
Private Sub SearchEvents()
Me.Cursor = Cursors.WaitCursor
Dim EventCount As Integer = 0
Dim service As CalendarService = GetCalendarService()
If objCalendars IsNot Nothing AndAlso objCalendars.Items.Count > 0 Then
For Each objCal As Data.CalendarListEntry In objCalendars.Items
If InStr(objCal.Description, "#") = 1 Then 'OPTIONAL: I decided adding this character in the first postion of the description of the calendar is a flag to indicate we search it.
Console.WriteLine("***NEW CALENDAR***: " & objCal.Summary)
Dim request As EventsResource.ListRequest = service.Events.List(objCal.Id)
If TextBox1.Text <> "" Then request.Q = Trim(TextBox1.Text)
request.SingleEvents = True
request.OrderBy = EventsResource.ListRequest.OrderByEnum.StartTime
Dim events As Events = request.Execute()
If events.Items IsNot Nothing AndAlso events.Items.Count > 0 Then
For Each eventItem In events.Items
If eventItem.Start.DateTime IsNot Nothing Then
Dim DateToShow As String = Format(eventItem.Start.DateTime, "MMM dd, \'yy hh:mmtt")
Console.WriteLine(DateToShow & ":" & eventItem.Summary & " > EventID: " & eventItem.Id & " > CalID:" & objCal.Id)
End If
EventCount += 1
Me.Text = EventCount.ToString
Next eventItem
End If
End If
Next objCal
End If
Me.Cursor = Cursors.Default
MsgBox("Total items: " & EventCount.ToString)
End Sub
Private Sub InsertEvent(ByVal Summary As String, ByVal Location As String, ByVal Description As String, ByVal StartDateTime As DateTime, ByVal DurationMinutes As Integer, ByVal CalendarID As String)
Dim service As CalendarService = GetCalendarService()
Dim newEvent As New [Event]() With {
.Summary = Summary,
.Location = Location,
.Description = Description,
.Start = New EventDateTime() With {.DateTime = StartDateTime, .TimeZone = calendarTimeZone},
.End = New EventDateTime() With {.DateTime = DateAdd(DateInterval.Minute, DurationMinutes, StartDateTime), .TimeZone = calendarTimeZone}
}
Dim request As EventsResource.InsertRequest = service.Events.Insert(newEvent, CalendarID)
Dim createdEvent As [Event] = request.Execute()
TestEventID = createdEvent.Id
TestCalendarID = CalendarID
Console.WriteLine("Event created:", createdEvent.Id)
End Sub
Private Function GetEvent(ByVal CalID As String, ByVal EventID As String) As [Event]
Dim service As CalendarService = GetCalendarService()
Dim request As EventsResource.GetRequest = service.Events.Get(CalID, EventID)
Dim ThisEvent As [Event] = request.Execute()
Return ThisEvent
End Function
End Class
Solution
If you take a look at the implementation of the Events.Get method you will see that the parameters are passed in the opposite way: first calendarId, then eventId
/// <summary>Returns an event.</summary>
/// <param name="calendarId">Calendar identifier. To retrieve calendar IDs call the calendarList.list method. If you
/// want to access the primary calendar of the currently logged in user, use the "primary" keyword.</param>
///
/// <param name="eventId">Event identifier.</param>
public virtual GetRequest Get(string calendarId, string eventId)
{
return new GetRequest(service, calendarId, eventId);
}
Reference
.NET Google Client API
I have created a login authentication using the Microsoft Graph API which means after I sign in, as a result, I have the access token of the current user signed-in. My next step is to create a Microsoft Teams Meeting on behalf of the current user signed-in.
I have tried to follow the Microsoft documentation Application POST onlinemeetings, where It shows the required steps to achieve this scenario.
Unfortunately, they didn't provide an example of how it can be achieved in VB.Net (which is not a big deal because I have converted the code to VB).
Currently, I am stuck on sending a POST request to generate this meeting based on the hard coded values when the user clicks on the button.
Please have a look at the code below:
Imports System.IO
Imports System.Net
Imports System.Net.Http
Imports System.Net.Http.Headers
Imports System.Threading.Tasks
Imports Microsoft.Graph
Imports Microsoft.IdentityModel.Clients.ActiveDirectory
Imports Newtonsoft.Json
Imports Newtonsoft.Json.Linq
Public Class _Default
Inherits Page
Private Shared httpClient As HttpClient = New HttpClient()
Private Shared context As AuthenticationContext = Nothing
Private Shared credential As ClientCredential = Nothing
Private Shared graphClient As GraphServiceClient
Private Shared authprovider As IAuthenticationProvider
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Dim code = HttpContext.Current.Request.QueryString("Code")
If Not Page.IsPostBack Then
If code <> "" Then
Dim url = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
Dim myParameters = "grant_type=authorization_code&code=" & code & "&redirect_uri=https://localhost:4312/&client_id=CLIENTID&client_secret=CLIENTSECRET"
Dim wb = New WebClient
wb.Headers(HttpRequestHeader.ContentType) = "application/x-www-form-urlencoded"
Dim response = wb.UploadString(url, "POST", myParameters)
responseToken.Text = response
Success.Text = "O365 login successful. Below is the response token"
Dim SurroundingClass = JsonConvert.DeserializeObject(Of SurroundingClass)(response)
Dim rss As JObject = JObject.Parse(response)
Dim token = rss.SelectToken("access_token")
Dim res = GetUsers(token)
End If
End If
End Sub
Private Shared Async Function GetUsers(ByVal result As String) As Task(Of String)
Try
Dim users As String = Nothing
Dim querystring As String = "api-version=1.6"
Dim uri = "https://graph.microsoft.com/v1.0/me"
httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", result)
httpClient.DefaultRequestHeaders.Accept.Add(New MediaTypeWithQualityHeaderValue("application/json"))
Dim User = GetMeAsync().Result
Console.WriteLine($"Welcome {User.DisplayName}!\n")
Dim getResult = Await httpClient.GetAsync(uri)
If getResult.Content IsNot Nothing Then
users = Await getResult.Content.ReadAsStringAsync()
End If
Return users
Catch ex As Exception
Throw ex
End Try
End Function
Protected Sub tes_Click(sender As Object, e As EventArgs)
Try
'Dim fr As System.Net.HttpWebRequest
Dim client_id = ""// App Client ID'
Dim uri = "https://localhost:4312/"
Dim targetURI As String = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize?client_id=" & client_id &
"&redirect_uri=" & uri & "&response_type=code&scope=openid+Mail.Read"
Response.Redirect(targetURI)
Catch ex As System.Net.WebException
'Error in accessing the resource, handle it
End Try
End Sub
Public Shared Async Function CreateMeeting() As Task(Of OnlineMeeting)
Try
graphClient = New GraphServiceClient(authprovider)
Dim onlineMeeting = New OnlineMeeting With {
.StartDateTime = DateTimeOffset.Parse("2020-04-23T21:33:30.8546353+00:00"),
.EndDateTime = DateTimeOffset.Parse("2020-04-23T22:03:30.8566356+00:00"),
.Subject = "Application Token Meeting",
.Participants = New MeetingParticipants With {
.Organizer = New MeetingParticipantInfo With {
.Identity = New IdentitySet With {
.User = New Identity With {
.Id = "MYID"
}
}
}
}
}
Dim encodings As New UTF8Encoding
Dim serializer As New JavaScriptSerializer()
Dim arrayJson As String = serializer.Serialize(onlineMeeting)
Dim result As String = Nothing
Dim postRequest As HttpWebRequest = DirectCast(WebRequest.Create("https://graph.microsoft.com/v1.0/me/onlineMeetings"), HttpWebRequest)
postRequest.Method = "POST"
postRequest.ContentType = "application/json"
httpClient.DefaultRequestHeaders.Authorization = New AuthenticationHeaderValue("Bearer", Token)
If postRequest.Method = "POST" Then
Dim parsedContent As String = JsonConvert.SerializeObject(onlineMeeting)
Dim encoding As ASCIIEncoding = New ASCIIEncoding()
Dim bytes As Byte() = encoding.GetBytes(parsedContent)
Dim newStream As Stream = postRequest.GetRequestStream()
newStream.Write(bytes, 0, bytes.Length)
newStream.Close()
End If
Dim createMeetings = Await graphClient.Communications.OnlineMeetings.Request().AddAsync(onlineMeeting)
Console.WriteLine("The meeting has been created")
Return createMeetings
Catch ex As ServiceException
Console.WriteLine($"Error while creating the meeting: {ex.Message}")
Return Nothing
End Try
End Function
Public Sub InvokeMeeting(sender As Object, e As EventArgs)
Try
Dim testing = CreateMeeting()
Catch ex As Exception
End Try
End Sub
PS: I have added the permission required to call this API to be able to create a Teams meeting.
Any suggestions on how to achieve the following scenario?
Any help will be greatly appreciated.
Thank you!
I'm trying to access a WCF WebService using VB.Net. So far I've succesfully set up the connected service via WSDL and exposed the methods and classes from the service.
The error I'm stuck at is
BC30311 - The value of type 'CatalogItemUpdateCommand' cannot be converted to 'CatalogItemUpdateCommand()'.
I have a class CatalogUpdateRequest, with a public property Items() set to another class, named CatalogItemUpdateCommand.
The code for CatalogItemUpdateCommand class:
Partial Public Class CatalogItemUpdateCommand
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
Private CatalogItemCodeField As String
Private PriceField As Decimal
Public Property CatalogItemCode() As String
Get
Return Me.CatalogItemCodeField
End Get
Set
If (Object.ReferenceEquals(Me.CatalogItemCodeField, value) <> true) Then
Me.CatalogItemCodeField = value
Me.RaisePropertyChanged("CatalogItemCode")
End If
End Set
End Property
Public Property Price() As Decimal
Get
Return Me.PriceField
End Get
Set
If (Me.PriceField.Equals(value) <> true) Then
Me.PriceField = value
Me.RaisePropertyChanged("Price")
End If
End Set
End Property
The code for CatalogUpdateRequest class:
Partial Public Class CatalogUpdateRequest
Inherits Object
Implements System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
Private ItemsField() As SEAP.CatalogItemUpdateCommand
Public Property Items() As SEAP.CatalogItemUpdateCommand()
Get
Return Me.ItemsField
End Get
Set
If (Object.ReferenceEquals(Me.ItemsField, Value) <> True) Then
Me.ItemsField = Value
Me.RaisePropertyChanged("Items")
End If
End Set
End Property
The code to call the service:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim items_to_update As CatalogItemUpdateCommand = New CatalogItemUpdateCommand
Dim items_update_request As CatalogUpdateRequest = New CatalogUpdateRequest With {.Items = items_to_update}
Dim final_update_request As Catalog_UpdateItemsRequest = New Catalog_UpdateItemsRequest(request:=items_update_request)
Try
'Assign values to parameters
items_to_update.CatalogItemCode = "00011587"
items_to_update.InStock = "true"
items_to_update.Price = 7.53
items_to_update.DoUpdatePrice = "true"
items_to_update.DoUpdateStock = "true"
items_to_update.DoPublish = "true"
items_to_update.DoProcessPublish = "true"
'Call the Catalog_UpdateItems method from the interface
seapclient.Catalog_UpdateItems(final_update_request)
Catch wex As WebException
End Try
End Sub
This line generates the error mentioned above:
Dim items_update_request As CatalogUpdateRequest = New CatalogUpdateRequest With {.Items = items_to_update}
I get the same error if I state:
items_update_request.Items = items_to_update
inside the Try... End Try block
BC30311 - The value of type 'CatalogItemUpdateCommand' cannot be converted to 'CatalogItemUpdateCommand()'.
It seems to be a declaration issue. Any suggestions?
Later edit: Thanks, guys, declaring ar array() seemed to have done the trick!
New code:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim items_to_update(1) As CatalogItemUpdateCommand
Dim items_update_request As CatalogUpdateRequest = New CatalogUpdateRequest() ' With {.Items = items_to_update}
Dim final_update_request As Catalog_UpdateItemsRequest = New Catalog_UpdateItemsRequest()
Dim update_response As Catalog_UpdateItemsResponse
Dim update_result As CatalogImportResponse
Try
'Assign values to parameters
items_to_update(0) = New CatalogItemUpdateCommand With {.CatalogItemCode = "00011587", .Price = 7.54, .DoUpdatePrice = "true", .InStock = "true", .DoPublish = "true", .DoProcessPublish = "true"}
'
items_update_request.Items = items_to_update
final_update_request.request = items_update_request
'Call the Catalog_UpdateItems method from the interface
update_response = seapclient.Catalog_UpdateItems(final_update_request)
txtResponse.Text = "Status: " & update_response.Catalog_UpdateItemsResult.Status.ToString & "Updated: " & update_response.Catalog_UpdateItemsResult.Updated.ToString() & "Failed: " & update_response.Catalog_UpdateItemsResult.Failed.ToString()
Catch wex As WebException
End Try
End Sub
Moving on to assigning values to array from SQL Database, keep in touch...
I'm developing a client that connects to my server, and get access to download and upload files, and i seem to be stuck at uploading files. Here is my code on my VB.NET client:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 'Upload button
WebBrowser1.Visible = True
'Style OpenFileDialog1
OpenFileDialog1.Title = "Select file to upload"
OpenFileDialog1.InitialDirectory = System.Environment.SpecialFolder.Desktop
OpenFileDialog1.ShowDialog()
End Sub
Private Sub OpenFileDialog1_FileOk(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles OpenFileDialog1.FileOk
uploadFile = OpenFileDialog1.FileName.ToString()
If uploadFile = Nothing Then
MessageBox.Show("You just selected nothing.", "Information")
Else
WebBrowser1.Document.GetElementById("fileselect").SetAttribute("value", uploadFile)
WebBrowser1.Document.GetElementById("submit").InvokeMember("click")
End If
End Sub
And here is the HTML code:
<input type="file" id="fileselect" name="fileselect[]" multiple="multiple" />
<button type="submit" id="submit" class="uploadButton">Upload Files</button>
Also how do i make so that i can select multiple files? Via the web version you can select multiple files and it workes not not here?
So, as mentioned in the comments, input elements of type file do not allow for external modification, all interaction with them is done through the browser and is based on direct user interaction.
However, you could create an upload class that process the multiple file upload to your server, by creating a HttpWebRequest, which sends the data to the form. Provided there is no authentication, it can be done in the following way.
An interface that allows for some elementary actions for post data items
Public Interface IPostItem
ReadOnly Property Title As String
Property ElementName As String
Function GetPostData(inputNameElement As String) As String
End Interface
Some way to define the mime type of the file being sent
Public NotInheritable Class MimeTypeHandler
Private Shared ReadOnly images As String() = {"jpg", "gif", "bmp", "png", "jpeg"}
Public Shared Function GetMimeType(filename As String) As String
Dim extension As String = Path.GetExtension(filename).Replace(".", "")
If (images.Contains(extension)) Then
Return "image/" + extension
End If
Return "application/" + extension
End Function
End Class
Implement the IPostItem with an implementation that can post the file
Public Class FileQueueItem
Implements IPostItem
Public Property FileName As String
Public Property ElementName As String Implements IPostItem.ElementName
Public Function GetData() As Byte()
Dim result As Byte() = Nothing
Dim lengthRead As Integer = 0
Using stream As New FileStream(FileName, FileMode.Open, FileAccess.Read)
ReDim result(stream.Length)
lengthRead = stream.Read(result, 0, stream.Length)
End Using
Return result
End Function
Public ReadOnly Property ShortName As String Implements IPostItem.Title
Get
Return FileName.Substring(FileName.LastIndexOf("\") + 1)
End Get
End Property
Public ReadOnly Property MimeType As String
Get
Return MimeTypeHandler.GetMimeType(FileName)
End Get
End Property
Public Function GetPostData(inputNameElement As String) As String Implements IPostItem.GetPostData
Dim message As String = String.Empty
message += String.Format("Content-Disposition: form-data; name=""{0}""; filename=""{1}""{3}Content-Type: {2}{3}Content-Transfer-Encoding: base64{3}{3}", inputNameElement, ShortName, MimeType, Environment.NewLine)
message += Convert.ToBase64String(GetData())
Return message
End Function
Public Sub New(filename As String, elementName As String)
Me.FileName = filename
Me.ElementName = elementName
End Sub
End Class
Have a small controller class that runs the upload sequence using the BackgroundWorker class, it sends the files per 5 (can be set, is default value).
It requires a FormUrl, to say where the form is that is being posted to, in my case, i was running it on my localhost, so that you would see in the form code
Public Class FileUploader
Inherits BackgroundWorker
Private ReadOnly _listQueue As IList(Of IPostItem) = New List(Of IPostItem)
Public Property FormUrl As String
Public ReadOnly Property ListQueue As IList(Of IPostItem)
Get
Return _listQueue
End Get
End Property
Public Property MaxPerQueue As Integer
Protected Function HandleResponse(request As HttpWebRequest) As Boolean
Dim success As Boolean = False
Try
Using response As HttpWebResponse = CType(request.GetResponse(), HttpWebResponse)
success = response.StatusCode <> HttpStatusCode.OK
End Using
Catch ex As WebException
If ex.Response IsNot Nothing Then
ex.Response.Close()
End If
End Try
Return success
End Function
Protected Sub Run(sender As Object, e As DoWorkEventArgs)
If ListQueue.Count = 0 Then
' nothing to upload
Return
End If
' create the boundary string, used to split between the separate attachments
Dim boundary As String = String.Format("--------------------------{0}", DateTime.Now.Ticks)
Dim count As Integer = 0
Dim totalFiles As Integer = ListQueue.Count
Do
' create the request
Dim request As HttpWebRequest = CType(WebRequest.Create(Me.FormUrl), HttpWebRequest)
Dim fullPostMessage As String = String.Empty
request.AllowAutoRedirect = True
request.KeepAlive = True
request.Referer = Me.FormUrl
''// say that it has to post data
request.Method = WebRequestMethods.Http.Post
''// same style like a form
request.ContentType = "multipart/form-data;boundary=" + boundary
count = 0
Dim queueItem As IPostItem
While count < MaxPerQueue AndAlso ListQueue.Count > 0
''// get the item in the queue
queueItem = ListQueue(0)
''// report potential changes to gui
Report(queueItem.Title, count, totalFiles)
Dim postAsString As String = queueItem.GetPostData(queueItem.ElementName)
fullPostMessage &= String.Format("--{0}{1}{2}{1}", boundary, Environment.NewLine, postAsString)
''// remove the item from the queue
ListQueue.RemoveAt(0)
count += 1
End While
fullPostMessage &= "--" & boundary & "--"
Dim postData As Byte() = System.Text.Encoding.ASCII.GetBytes(fullPostMessage)
''// write data to the requestStream (post data)
request.ContentLength = postData.Length
Dim requestStream As Stream = request.GetRequestStream()
requestStream.Write(postData, 0, postData.Length)
requestStream.Close()
''// handle the response
HandleResponse(request)
requestStream.Dispose()
Loop While ListQueue.Count > 0
ListQueue.Clear()
Report("(Idle)", 0, 100)
End Sub
Protected Sub Report(filename As String, fileIndex As Integer, maxFiles As Integer)
Dim percentage As Integer = (fileIndex * 100) / maxFiles
ReportProgress(percentage, filename)
End Sub
Public Sub New()
Me.WorkerReportsProgress = True
AddHandler Me.DoWork, AddressOf Run
MaxPerQueue = 5
End Sub
End Class
Then you could create your form like this:
And then add the FileUploader class as a private member, so you can get notified when it has completed the upload stream, add the eventhandlers to get notified on the changes
Imports System.ComponentModel
Imports System.Net
Imports System.IO
Public Class Form1
Private fileUploadHandler As New FileUploader()
Private Sub btnUploadFiles_Click(sender As Object, e As EventArgs) Handles btnUploadFiles.Click
fileUploadHandler.FormUrl = "http://localhost:5555/Default.aspx"
Using openDialog As New OpenFileDialog
openDialog.Multiselect = True
openDialog.Title = "Select files to upload to the server"
If openDialog.ShowDialog() Then
' all files are selected
For Each fileName As String In openDialog.FileNames
Dim qItem As IPostItem = New FileQueueItem(fileName, "fileInfo[]")
fileUploadHandler.ListQueue.Add(qItem)
Next
btnUploadFiles.Enabled = False
fileUploadHandler.RunWorkerAsync()
End If
End Using
End Sub
Private Sub OnUploadCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
btnUploadFiles.Enabled = True
End Sub
Private Sub OnReportProgress(sender As Object, e As ProgressChangedEventArgs)
pbUploadProgress.Value = e.ProgressPercentage
lblUploadProgress.Text = e.UserState
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
AddHandler fileUploadHandler.RunWorkerCompleted, AddressOf OnUploadCompleted
AddHandler fileUploadHandler.ProgressChanged, AddressOf OnReportProgress
End Sub
End Class
The files get then uploaded as soon as you click the Open button in the OpenFileDialog.
As to your second question, to allow for more than 1 file selected, you have to set the OpenFileDialog.Multiselect = True flag
I am developing a VB.NET program to search for text in a specified column from a Datagrid. I am almost finished implementing this following the MS tutorial at:
http://support.microsoft.com/kb/815680
But now I have just one compilation error:
BC30456: 'Fill' is not a member of
'System.Web.UI.WebControls.DataGrid'.
on the line that says:
dgTable.Fill(ds)
The code related to this project is as follows. Does anybody know how I can fix this please?
My global.vb file:
Namespace GlobalFunctions
Public Class GlobalF
Public Shared Function GlobalF_Load(ByVal dgTable As DataGrid)
dgTable.Fill(ds)
dv = New DataView(ds.Tables)
dgTable.DataSource = dv
dv.Sort = "Part No."
CM = (System.Windows.Forms.CurrencyManager)
dgTable.BindingContext([dv])
Dim sender As New sender()
dv.ListChanged += New ListChangedEventHandler(dv_ListChangedEvent)
End Function
Public Shared Function btnFind_Click(ByVal sender As Object, ByVal e As EventArgs)
If (txtFind.Text = "") Then
Response.write("Enter some criteria to find.")
txtFind.Focus()
Else
Dim i As Int
i = dv.Find(txtFind.Text)
If (i > dv.Table.Rows.Count Or i < 0) Then
Response.Write("Record Not found")
Else
CM.Position = i
End If
End If
End Function
Private Shared Function dv_ListChangedEvent(ByVal sender As Object, ByVal e As ListChangedEventArgs) Handles btnFind.ListChanged
If (dv.Sort.Substring((dv.Sort.Length - 4), 4) = "DESC") Then
lblFind.Text = "Enter Search Criteria " + dv.Sort.Substring(0, dv.Sort.Length - 5)
Else
lblFind.Text = "Enter Search Criteria " + dv.Sort
End If
End Function
And my ASPX file:
Public DSTableData As New System.Data.DataSet
Public dv As New DataView
Sub Main()
'------------------------- Query database and get arrays for the chart and bind query results to datagrid ----------------------------------------
If check1.Checked Then
DSTableData = GlobalFunctions.GlobalF.FillSparePartsTable(1)
Else
DSTableData = GlobalFunctions.GlobalF.FillSparePartsTable(0)
End If
'dv = DataView(DSTableData(0))
dgTable.DataSource = DSTableData
dgTable.DataBind()
GlobalFunctions.GlobalF.GlobalF_Load(dgTable)
End Sub
Private Sub DataGrid1_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs)
If e.Item.ItemType = ListItemType.AlternatingItem Or e.Item.ItemType = ListItemType.Item Then
Dim thepriority As Integer
...
Now I have modified above code as follows:
Public Shared Function GlobalF_Load(ByVal dgTable As DataGrid)
Dim dv As New DataView
Dim ds As New DataSet
dv = New DataView(ds.Tables())
dgTable.DataSource = dv
dv.Sort = "Part No."
CM = (System.Windows.Forms.CurrencyManager)
dgTable.BindingContext([dv])
Dim sender As New sender()
But now I get a different error:
BC30311: Value of type
'System.Data.DataTableCollection'
cannot be converted to
'System.Data.DataTable'
Also, I'm not sure if it is good to be declaring these variables new like this since I believe I already call them new elsewhere in my code.
Instead of:
dgTable.Fill(ds)
dv = New DataView(ds.Tables)
dgTable.DataSource = dv
try:
dv= New DataView(ds.Tables("table name")
dgTable.DataSource = dv