im trying to upload multiple file and save all the files in a data table.
the data table is storing only one file.
Help me to solve, im having error in the else part. dtupload is highlighted
Below is what I have tried:
Private Sub AjaxFileUpload1_UploadComplete(sender As Object, e As AjaxControlToolkit.AjaxFileUploadEventArgs) Handles AjaxFileUpload1.UploadComplete
Try
dt.Rows.Add(UploadDocPath, UploadDoc)
MsgBox(dt.Rows.Count.ToString)
Else
dt.Rows.Add(UploadDocPath, UploadDoc)
End If
Catch ex As Exception
End Try
End Sub
Well, you in ONE local routine create a table, add a row. And then the routine finishes and all the values, variables now go out of scope. Then that routine will be called again if a 2nd file is up-loaded, and you re-create the table. The variables in that routine (and in fact ANY routine - heck even if this was not asp.net go out of scope when the routine finishes.
At least with a desktop application you could declare the table at the form level (not sub routine level) and then you could add a new row to that temp table variable. But, with asp.net, then your web page is "state less". That means all variables ONLY have their state when code runs. The instant that code is finished, then all state in the code behind is lost.
But I am somewhat perplexed that you would think the data table would persist for each call? Perhaps you only want the var dtUpload to exist in the lifetime of each separate time that routine is called? But, then again you do nothing with the table????
So, for each file up-loaded? That routine gets called.
So, lets assume 5 files are to be up-loaded.
Taking a really wild guess? I would assume we want that table/array to build up over time.
So, we need to ensure that the dtUpload table can "live" beyond a single page cycle and round trip.
So, lets save/place/put/park the dtUpload table that can live "beyond" that one routine.
It really depends on what you want to do with that list after all is said and done?
Since the table is small? Then you could certainly in the forms on-load event create that table with no rows and shove it into say the Session(). Then as each file up-loads you could shove the file name into that array.
So, your code could work like this:
In on-load event only FIRST time, create the dtUpload table. And then shove/save it into the session().
So, our on-load would look like this:
If IsPostBack = False Then
' fist time page load - create our table
Dim dtUpload As New DataTable
dtUpload.Columns.Add("PATH")
dtUpload.Columns.Add("FILENAME")
Session("FileList") = dtUpload
End If
Ok, so when the page loads (first time only), we create the dtTable and THEN save it in the session.
Now, in the file upload done event, grab the table from session, add the row (file + path).
And note HOW we don't have to shove the dtUpload table BACK into the session! (it is now a persisting object in our session).
Ok, so now our single file load event (when done) can/will look like this:
Protected Sub AjaxFileUpload1_UploadComplete(sender As Object,
e As AjaxControlToolkit.AjaxFileUploadEventArgs) Handles AjaxFileUpload1.UploadComplete
Dim dtUpload As DataTable = Session("FileList")
Dim strPath As String = "c:\Test\MyUpload\"
Dim strFile As String = e.FileName
dtUpload.Rows.Add(strPath, strFile)
AjaxFileUpload1.SaveAs(strPath & strFile)
End Sub
So, note how we add the one row to the table. (and we don't as noted have to shove the object back into the session - dtUpload in this case is in effect a object pointing to persisting dtUpload table we placed into Session().
Ok, so, now lets say all 5 files are done.
Well, you now have to decide what you want to do with the dtUpload table you have?
Perhaps we want to display all the files?
Well, keep in mind that the web page does not do a post back.
But, lets assume we now want to display all files.
Drag onto the form a datagrid control.
Drag onto the form a button.
So, we now have this:
Then hit up-load, you get this:
When you click on the the button, you can run this code:
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.GridView1.DataSource = Session("FileList")
Me.DataBind()
End Sub
And now click on that button?
And you see this:
Now here is a really huge, large, massive, VERY important reason why placed that button on the form. The reason of course is when the ajax upload is all done?
The web page does NOT do a post back. So, that is where the button above comes into play.
By clicking the button, then our code stub runs, we fill the gridview, and then of course the page makes the round trip and re-displays our file list.
Now, we could have the final CLient side ajaxfileupload event click on that button for us, and thus in place of the user clicking that button to continue?
You can have client side code click on that button for you.
So, set the OnClientUpLoadCompleteAll to the js routine:
<script>
function uerror() {
alert('upload error');
}
function myalldone() {
var btn = document.getElementById('<%=Button1.ClientID%>');
btn.click();
}
</script>
So it will now click that button (you could even set style="display:none" for the button. So, now you have a final routine server side, but with a full page post back.
Related
I have a combo box for selecting contact names. OnChange, it is supposed to trigger a requery of a list, so that the query filter updates. When I use the combobox pulldown, it works perfectly, but when I update the combo box from a secondary form, it does not work.
I am using arguments on the DoCmd.OpenForm To open the secondary form (which is a search form):
Set ctrl = Me.txtContactName
DoCmd.OpenForm "FindContactForm", , , , , , Me.Form.Name & ";" & ctrl.Name
The main form code is:
Private Sub txtContactName_Change()
MsgBox "Change Ocurred"
Me.listCallHistory.Requery
Refresh
End Sub
It should be noted that the debugging msgBox only appears when I use the combobox manually, so I must not be triggering the Change event when updating the combobox using the secondary form.
The secondary form code is:
Private Sub listContacts_DblClick(Cancel As Integer)
If IsNull(Me.listContacts.Column(0)) Then Exit Sub
If Not IsNull(Me.OpenArgs) Then
arrSplitStrings = Split(Me.OpenArgs, ";")
Forms(arrSplitStrings(0)).Controls(arrSplitStrings(1)).Value = Me.listContacts.Column(0)
DoCmd.Close
End If
End Sub
I'd appreciate any help, both in understanding why the onChange event is not ocurring, and also on how to implement a solution. My goal is to be able to use this search form from multiple parent forms, so I don't want to hardcode the parent form or control into it. It should be noted, that I can successfully requery the list from the search form, but that starts deviating from the goal; or requires an extra parameter to be passed and parsed. It'd work, but I'd like to understand what is going on.
In short, remaining in the HTTP context, I would like the user, after clicking on an order completion button, not to wait for the mails to be sent before being sent back to a "thak you page".
I saw that HostingEnvironment.QueueBackgroundWorkItem could help me with this but there is always the risk of it being killed by IIS recycling.
What is the best solution to do this?
I know the best would be to develop a separate console solution but it wouldn't be worth it for 3/4 emails, alternatively I could consider speeding it up by making them asynchronous?
Protected Sub btnConcludiOrdine_Click(sender As Object, e As System.EventArgs) Handles btnConcludiOrdine.Click
If IsValidOrder(Me._cart, msg) Then
If Me._cart.SaveOrder(Me._user, Me._orderCode, Me._lang) then
'Update quantity in db
Dim mail As New EmailBLL
mail.SendOrderNotice(Me._cart, Me._lang) '2 Mails
mail.SendProductNotice() '2 Mails
End If
Else
Response.Redirect("*Error URL*")
End If
End Sub
The way you approach this is as suggested – start a task, or so called new processor thread.
So, what you would do is break out the code – this even works if code behind is for a web form.
So, the first step is to move out the “slow” parts, or the parts we want to run separate.
The main issue is that to start/launch/want/desire/achieve a brand new processor thread?
The sub call CAN ONLY PASS ONE “parameter” and the sub can only accept one parameter!!!!!
I note in your case that routine needs two values.
However, that “one parameter” can be a array of “many” values, or even a collection or whatever. In our case we pass the two values.
So just keep in mind that what you call can NOT update or “use” the values of controls on the form – the instance of that form will go out of scope.
But we can of course PASS the values you need. This will allow that routine to run 100% independent of the web form.
I also VERY strong suggest that if you DO place the sub in the same web page code behind? You should/can mark that sub as shared. Doing so will allow the compiler to get mad at you and spit out errors if that routine say tries to use or update a control value on the form.
However, it is MUCH better is to place this sub in a separate standard code module out side of the web forms code behind.
Regardless of above, we can now re-write the code we have as this:
If Me._cart.SaveOrder(Me._user, Me._orderCode, Me._lang) then
Dim myInfo(1) as object
myInfo(0) = me.cart
myInfo(1) = me_._lng
Call MyUpdateQ(myInfo)
End If
' bla bla lba
Shared Sub MyUPdateQ(p() as object)
'Update quantity in db
Dim mail As New EmailBLL
mail.SendOrderNotice(p(0),p(1)
mail.SendProductNotice() '2 Mails
End Sub
Ok, so far, we not achieved much, but we re-writing to accept the ONE array is KEY here.
So, now now make sure the above runs/works and is all happy.
Now, because we moved out the "work load" to that one routine, it is now a simple matter to start a thread.
Now, Our above code becomes this:
Protected Sub btnConcludiOrdine_Click(sender As Object, e As System.EventArgs) Handles btnConcludiOrdine.Click
If IsValidOrder(Me._cart, msg) Then
If Me._cart.SaveOrder(Me._user, Me._orderCode, Me._lang) then
Dim myInfo(1) as object
myInfo(0) = me.cart
myInfo(1) = me_._lng
Dim MyThread As New Thread(New ParameterizedThreadStart(AddressOf MyUpdateQ))
MyThread.Start(myInfo)
End If
Else
Response.Redirect("*Error URL*")
End If
End Sub
Shared Sub MyUPdateQ(p() as object)
'Update quantity in db
Dim mail As New EmailBLL
mail.SendOrderNotice(p(0),p(1)
mail.SendProductNotice() '2 Mails
End Sub
That is it. Now when you click your button it will wait ZERO time, since the long running routine is now going to run 100% as a separate thread. And this will also mean that when the user clicks the button - the page will respond instant and post back to user will be done. So if that thread takes 6 seconds, or even 25 seconds, the user will not notice this delay.
Just push your sending mail logic in Task and if you are not interested in result don't await it. c# syntax
Task.Run(() => SendEmail());
I'm trying to get a timer to move between 3 Views in a MultiView control here is the code I'm using:
Protected Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim activeView As String
activeView = MultiView1.GetActiveView().ID
If activeView = "View1" Then
MultiView1.SetActiveView(View2)
End If
If activeView = "View2" Then
MultiView1.SetActiveView(View3)
End If
If activeView = "View3" Then
MultiView1.SetActiveView(View1)
End If
End Sub
On page load I have the MultiView Control set to View1 (MultiView1.SetActiveView(View1))
The page loads correctly and the data (being pulled from an SQL server is visible. After the first tick on timer1 the second view appears again showing the correct data. Then nothing I can see the reload button on the browser going at the timer interval but I never see View3 or a return to View1
Before anyone suggests I had build the If statement as If, ElseIf, EndIf but I broke it out into separate If statements to see if that would help.
It didn't.
I Hope someone can help
Cheers
Have you tried to debug your code with breaks, try to put a break in the If...End If blocks and watch if it is reachable.
You may be having different IDs set for your views, or maybe some cASE mismatching. I will suggest, rather comparing view's ID string, it is safe to compare views index by MultiView1.ActiveViewIndex, this will return only an integer which is lot safer to compare.
Hope it will work.
Sometimes I wonder if I should be let out without a carer.
I found out why the views or label.text changes weren't progressing. I had set the startup info in page_load so even though the timer was firing it was doing a page_load which was defaulting back to the original data.
Sorry for the waste of your time.
I'm off to slowly bang my head against the wall until it doesn't hurt anymore then return to my project.
I'm trying to eliminate a VB.NET button on my aspx page. Trying to use javascript and ajax to execute the same code my vb had.
I put in a script manager, set EnablePageMethods to true, added a static subroutine, and referred to it in my javascript function (BTW -- this seems a lot of work just to execute an existing subroutine). The javascript calls my code-behind and it almost works.
Problem is, now I'm getting a NullReferenceException when SimulatePrintBatchClick tries to do anything with the controls.
Error is 'Object reference not set to an instance of an object', line is 'pnlVars.Controls.Clear'
Here's the code from UW.aspx:
<WebMethod()> _
Public Shared Sub PrintBatchFromJSWM()
Dim UWI As New UW
UWI.SimulatePrintBatchClick()
End Sub
Sub SimulatePrintBatchClick()
Dim Client As New LetterWriterClient
'Run ExStream and get the PDF File
Globals.PDF_Data = Nothing
Globals.PDF_Data = Client.ProcessDatFile(Session("SessionID").ToString)
'Reload the form -- turn off all controls, initialize variables and make the PDF iFrame visible
pnlVars.Controls.Clear() 'Bombs out on THIS line of code
pnlPDF.Visible = True
Me.SendToBach.Visible = False
Session.Contents("LetterVariables") = Nothing
Session.Contents("PolicyInformation") = Nothing
Session.Contents("Submitted") = True
Response.Redirect("UW.aspx")
End Sub
Funny, when I run the above code in PrintBatch_Click it all executes just fine. I really don't understand why it bombs out as a subroutine.
Perhaps this is not the way to do this, but I'm at a loss for finding a different way. Originally this code was handled by an ASP/VB button, but the specs have called for it to be deleted.
Any way I can get the above code to do it's job?
Thanks,
Jason
You cannot use any server controls in WebMethod or AjaxMethod as they are not part of Page life cycle, access these controls in Javascript.
I'm developing a web application that displays items from a work queue to a user. When an item is selected I have the app lock that item out so no other user can select it. By hitting the back button in the app it unlocks the item.
I want to be able to unlock the item if the user hits the backspace key. I know what code I need to unlock it. I just need to know how to make the code execute on backspace key stroke.
The code that I need to execute will be server side code.
Thanks in advance.
<script>
document.onkeydown = function (e)
{
if (window.event && window.event.keyCode == 8) {
__doPostBack('__Page', 'MyCustomArgument');
}
}
</script>
If you need to execute code on server, you have to change your question accordingly
EDIT:
You could set a Hiddenfield's value to f.e. "unlockItem" and do a document.forms[0].submit() and checkthe hidden-value on serverside or better:
Use the clientside __doPostBack function generated from ASP.Net to submit page(for example on selectedIndexChanged of a DropDownList). You could even generate it from Codebehind if you want the cleanest way.
I changed the above code, but i think your next question could be how you should know which item was selected, won't it?
Then you have to clarify what items we are talking about.
On serverside you get the passed arguments with:
If Page.IsPostBack Then
Dim eventArg As String = Request("__EVENTARGUMENT")
End If
End If