Good Afternoon.
I'm working with the following web pages using ms vwd 2010 express:
Site.Master/Site.Master.vb, Login.aspx/Login.aspx.vb
The Site.Master has the following:
<div class="loginDisplay">
<asp:Label ID="WelcomeLabel" runat="server" Text=""></asp:Label>
<asp:HyperLink ID="LogHyperlink" navigateurl="~/Account/Login.aspx" runat="server">Log In</asp:HyperLink>
</div>
I have the following code in the Login.aspx.vb program:
Dim WelcomeLabel As New Label
WelcomeLabel = CType(Master.FindControl("WelcomeLabel"), Label)
WelcomeLabel.Text = "Welcome " & OLEdr.Item("ho1FirstName")
Dim LogHyperlink As New HyperLink
LogHyperlink = CType(Master.FindControl("LogHyperlink"), HyperLink)
LogHyperlink.Text = "Log Out"
LogHyperlink.NavigateUrl = "Exit.aspx"
When a user logs in successfully the LogHyperlink is changed from Log In to
Log Out and the WelcomeLabel contains the text "Welcome " and person's first name. This all works fine.
However, the code only works for the Login.asp page. When I navigate to another
page, say About.aspx (which also uses the Site.Master), the Site.Master
page is back to the orginal and I have lost the changes the code made.
How can I make the changes persist for the session across all the
web pages? All the web pages use the Site.Master.
Thank you.
tfj
Have a look at the LoginView control. It seems you're trying to implement exactly what that control is for. It allows you to display different information depending on whether a user is logged in or not.
It is doable ( although I don't recommend it). In Login.aspx.vb add a line to save the user name in session:
Session("LoggedInUser") = OLEdr.Item("ho1FirstName").ToString()
Dim WelcomeLabel As New Label
WelcomeLabel = CType(Master.FindControl("WelcomeLabel"), Label)
WelcomeLabel.Text = "Welcome " & OLEdr.Item("ho1FirstName")
Dim LogHyperlink As New HyperLink
LogHyperlink = CType(Master.FindControl("LogHyperlink"), HyperLink)
LogHyperlink.Text = "Log Out"
LogHyperlink.NavigateUrl = "Exit.aspx"
In Site.Master.vb load the username from Session in Page_Load:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not Session("LoggedInUser") Is Nothing Then
WelcomeLabel.Text = Session("LoggedInUser").ToString()
LogHyperlink.Text = "Log Out"
LogHyperlink.NavigateUrl = "Exit.aspx"
Else
LogHyperlink.Text = "Log In"
LogHyperlink.NavigateUrl = "~/Account/Login.aspx"
WelcomeLabel.Text = ""
End If
End Sub
Related
I am creating a drag file upload by using Ajax File Upload Control in Asp.net(VB).
I want to show file name, uploaded datetime, file size when I dragged into panel.
How can I do for that setting?
I could change the text for droparea like
$(document).ready(function () {
Sys.Extended.UI.Resources.AjaxFileUpload_Pending = "保留中";
Sys.Extended.UI.Resources.AjaxFileUpload_Remove = "削除";
Sys.Extended.UI.Resources.AjaxFileUpload_Uploaded = "アップロード済";
Sys.Extended.UI.Resources.AjaxFileUpload_Uploading = "アップロード中";
Sys.Extended.UI.Resources.AjaxFileUpload_UploadedPercentage = "アップロード中 {0} %";
Sys.Extended.UI.Resources.AjaxFileUpload_Upload = "アップロード";
document.getElementsByClassName
$(".ajax__fileupload_dropzone").text("ここにファイルをドロップ");
document.getElementsByClassName
$(".ajax__fileupload_uploadbutton").text("アップロード");
});
But I don't know how to change file info display.
This is my drag form and I want to change from application/pdf to uploaded datetime
You can't really display the "time" of up-load until the user starts.
You ALREADY can see the file size in your screen cap, so why the need for that?
you have:
so in above, you see the file name, you see the file size.
However, until such time you hit up-load and start up-loading files, you don't know yet the up-load time as of yet, do you?
So, when you hit up-load files, then each file selected will be up-loaded, and in the server side (code behind), you have this:
Protected Sub AjaxFileUpload1_UploadComplete(sender As Object, e As AjaxControlToolkit.AjaxFileUploadEventArgs) Handles AjaxFileUpload1.UploadComplete
Dim strFileSave As String
strFileSave = Server.MapPath("~/Content/" & e.FileName)
AjaxFileUpload1.SaveAs(strFileSave)
' now code to add say to a database table of files up-loaded.
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL = "INSERT INTO MyUpoadFiles (FileName, UpLoadTime, Size, User_id) " &
"VALUES (#File, #Time,#Size, #User)"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
With cmdSQL.Parameters
.Add("#File", SqlDbType.NVarChar).Value = e.FileName
.Add("#Time", SqlDbType.DateTime).Value = Date.Now
.Add("#Size", SqlDbType.Int).Value = e.FileSize
.Add("#User", SqlDbType.Int).Value = Membership.GetUser.ProviderUserKey
End With
cmdSQL.ExecuteNonQuery()
End Using
End Using
End Sub
Now, when ALL files are up-loaded, then the server side even UpLoadComplete all will fire, and THEN you can take the above list/table and display the files up-loaded along with the FileName, size, and time.
But, you really don't have the ability to display the file information such as what time until such time you uploaded the file and then have the time, right?
Edit:
Perhaps the idea above was not all that clear. What I am suggesting is that you have the up-loader on the page.
So, say we drop in this markup:
<div style="width:40%;padding:25px">
<ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server"
OnClientUploadCompleteAll="MyCompleteAll" ChunkSize="16384" />
<asp:Button ID="cmdDone" runat="server" Text="Done" CssClass="btn" ClientIDMode="Static"/>
<script>
function MyCompleteAll() {
$('#cmdDone').click()
}
</script>
<asp:GridView ID="Gfiles" runat="server" CssClass="table"></asp:GridView>
</div>
And note how we use the client side all done click.
So, we now have this:
We hit upload, and now we see this:
Now we should (need to) hide the Done button - we have the upload clicking on that done button for us.
So that button in theory should become this to hide it:
<asp:Button ID="cmdDone" runat="server" Text="Done"
style="display:none" ClientIDMode="Static"/>
And the code for that button is this:
Protected Sub cmdDone_Click(sender As Object, e As EventArgs) Handles cmdDone.Click
Dim rstFiles As New DataTable
Using conn As New SqlConnection(My.Settings.TEST4)
Dim strSQL As String = "select FileName, UpLoadTime, Size, User_id from MyUpLoadFiles"
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
rstFiles.Load(cmdSQL.ExecuteReader)
End Using
End Using
Gfiles.DataSource = rstFiles
Gfiles.DataBind()
' hide up-loader
AjaxFileUpload1.Visible = False
End Sub
I'm dynamically adding htmlvideo controls to my web form based on the number of videos present on the server folder. This part works fine. All the videos show up and can be played. I add the 'onended' event as an attribute and the function in my code behind, but this event won't fire. I'm aware that since these controls are added after the fact I have to add a listener, but just don't know how.
This is the code that adds the controls
Dim SavePath As String = "e:\ftproot\images\TechNet\"
Dim Directory As New DirectoryInfo(SavePath)
Dim allFiles As IO.FileInfo() = Directory.GetFiles("*.mov")
Dim VidCtr As Integer = 1
For Each singlefile In allFiles
Dim myVid As New HtmlVideo
myVid.Src = "https://www.rawauto.com/images/TechNet/" & singlefile.Name
myVid.Attributes.Add("height", 140)
myVid.Attributes.Add("runat", "server")
myVid.Attributes.Add("type", "video/mp4")
myVid.Attributes.Add("controls", "controls")
myVid.Attributes.Add("onended", "VidPlayed")
myVid.Attributes.Add("id", "Vid" & VidCtr)
Panel1.Controls.Add(myVid)
Dim myLbl As New Label
myLbl.Text = Replace(UCase(singlefile.Name), ".MOV", "")
myLbl.Width = 250
myLbl.CssClass = "VidStyle"
myLbl.Font.Name = "calabri"
myLbl.Font.Bold = True
LPanel.Controls.Add(myLbl)
Next
This is the function I'm trying to fire once the user has finished watching the video:
Protected Sub VidPlayed(sender As Object, e As EventArgs)
Dim Tech As New SqlConnection("server=RAW-OTT; Initial Catalog=TechNet; Integrated Security=True;")
Dim vid As HtmlVideo = sender
Dim vidurl As String = vid.Src
VidName = Replace(vidurl, "https://www.rawauto.com/images/TechNet/", "")
If Len(VidName) > 50 Then
VidName = Mid(VidName, 1, 50)
End If
Dim SqlStr As String = "Select * From TechTube Where Video = '" & VidName & "'"
Dim ttA As New SqlDataAdapter(SqlStr, Tech)
Dim ttT As New DataTable
ttA.Fill(ttT)
If ttT.Rows.Count = 0 Then
SqlStr = "Insert Into TechTube Values ('" & VidName & "', 1, 0)"
Dim tCmd As New SqlCommand(SqlStr, Tech)
Tech.Open()
tCmd.ExecuteNonQuery()
Tech.Close()
Else
SqlStr = "Update TechTube Set Hits = Hits + 1 Where Video = '" & VidName & "'"
Dim tCmd As New SqlCommand(SqlStr, Tech)
Tech.Open()
tCmd.ExecuteNonQuery()
Tech.Close()
End If
RateLabel.Visible = True
RatingBox.Visible = True
End Sub
This is an old ViewState problem for any dynamic control, and has nothing specific to do with video.
Remember, every PostBack rebuilds the entire page from scratch, including your dynamic controls. If you still want to see these controls after a postback (which includes all server events), you must re-add them to the page. Additionally, you need a control's ViewState restored if you want an event fired for the control during this PostBack, and for the ViewState to restore the control must be added back to the reconstructed page before the Page_Load event runs. Page_Init or Page_PreInit can work well for this.
Finally, consider the performance implications here. Do you really want to rebuild the entire page on every user interaction, or is it perhaps time to learn to use javascript to process these things, with maybe a web api that only has to receive a javascript request without causing an entire page cycle both on your server and in the user's browser?
Just a few of the many other times this has been asked and answered:
Dynamic Event Handler not Firing
dynamically added buttons not firing click event c#
dynamically created button click event not firing
Dynamically Added DropDownlists Are Not Firing SelectedIndexChanged Event
ASP.NET: Viewstate and programmatically adding user controls
Click events on Array of buttons
VB ASP dynamic button click event not hitting handler event
I appreciate help for this issue which stoled a lot of hours.
I have this code:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
Label1.Text = "924 695 302"
Label2.Text = "690 142 449"
Dim ipvisitante = Request.ServerVariables("remote_addr")
Dim hoje = DateTime.Now
Dim informacao = ipvisitante & " --- " & hoje
'Send e-mail
Dim strFrom = "fernandopessoa#fpessoa.net" ''IMPORTANT: This must be same as your smtp authentication address.
Dim strTo = "francopessoa.espana#hotmail.com"
Dim MailMsg As New MailMessage(New MailAddress(strFrom.Trim()), New MailAddress(strTo))
MailMsg.BodyEncoding = Encoding.Default
MailMsg.Subject = "This is a test"
MailMsg.Body = "This is a sample message using SMTP authentication"
MailMsg.Priority = MailPriority.High
MailMsg.IsBodyHtml = True
'Smtpclient to send the mail message
Dim SmtpMail As New SmtpClient
Dim basicAuthenticationInfo As New Net.NetworkCredential("fernandopessoa#fpessoa.net", "---------")
''IMPORANT: Your smtp login email MUST be same as your FROM address.
SmtpMail.Host = "mail.fpessoa.net"
SmtpMail.UseDefaultCredentials = False
SmtpMail.Credentials = basicAuthenticationInfo
MsgBox("O ficheiro existe", MsgBoxStyle.Information, "SIM")
'Write to txt File
FileOpen(1, "visitas.txt", OpenMode.Append)
WriteLine(1, informacao)
FileClose()
End Sub
Now, when the page Loads, the text apears in the Labels.
Surprisingly, it doesn't execute the rest of the code, Display Msgbox, Write to the .txt File and send the e-mail.
Can anyone give me a clue of what's going wrong with my code?
Thanks in advance.
The code does execute... it runs on the Web Server. It does not run in the client's web browser, and never will.
That explains the MsBox() and file, though the web server may also be getting hung up waiting for someone to click "Okay" on a MsgBox no one will ever see. For the e-mail, you never call SmtpMail.Send(MailMsg)
While I'm here, that file code is using an antique api.
It sounds like you need a quick primer on how this all works, so here is what happens step by step:
User clicks a link to your page or types your page address in their address bar.
The browser sends an HTTP request to your server.
Your server receives the request, creates a new instance of your page class in a worker thread.
Code runs in your page class for ALL phases of the ASP.Net Page Lifecycle .
The ASP.Net runtime uses your page class instance to render an HTTP response (usually in html) and send it to the browser.
Your page class instance is destroyed.
The browser receives the response, parses a new Document Object Model (DOM), and renders that DOM to the display.
The user sees and interacts with your page, causing a post-back.
Go to step 2, taking special note of the "new instance" phrase when you reach step 3.
I have a web app which displays a list of emails that need to be sent for the day. The user can select what emails to send, then click a button to generate them. When they click the Send button, a process gets started on another thread which generates the emails, then cleans up after itself by deleting a temp folder. Once the process is finished, the Repeater is rebound to update the User's view and remove the emails that have just been sent so they don't get sent again.
My problem is that when I delete the temp folder from my 2nd thread, the UI doesn't update with the new Repeater data. It updates correctly if I just delete the files in the folder instead of the folder itself, and it also updates correctly if I run the delete the folder on the original thread instead of the 2nd one.
New Thread code
Dim t as Thread = New Thread(New ThreadStart(AddressOf EmailLetters))
t.Start()
Delete folder code
Dim fs = Server.CreateObject("Scripting.FileSystemObject")
fs.DeleteFolder(Server.MapPath(".") + "\tmpEmailFiles")
Why won't the UI update to show the new repeater values when I delete a folder on another thread?
EDIT
Here is some sample code that shows the problem. Sorry if its a bit messy, but I just needed something simple to help me identify the problem.
When you click the button, a thread gets started and a javascript load script starts executing which does a PostBack every 10 seconds. Each postback checks if the thread is complete and updates the Status label showing the result. If I delete a folder from within the background thread, the final update to the status label never occurs. If I remove the DeleteFolder call, it does.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%# Import Namespace="System.Threading" %>
<%# Page Language="VB" Debug="true" %>
<%# Implements Interface="System.Web.UI.IPostBackEventHandler" %>
<SCRIPT language="vb" runat="server">
Sub Page_Load(Src As Object, e As EventArgs)
End Sub
Public Sub Test(src as Object, e as EventArgs)
Dim t as Thread = New Thread(New ThreadStart(AddressOf TestWorker))
t.Start()
Session("BackgroundThread") = t
End Sub
Public Sub TestWorker()
' 30 Second Delay
System.Threading.Thread.Sleep(30000)
Dim root as String = Server.MapPath(".")
Dim fs = Server.CreateObject("Scripting.FileSystemObject")
If Not fs.FolderExists(root + "\Test") Then fs.CreateFolder(root + "\Test")
fs.DeleteFolder(root + "\Test")
ErrMsg.Text = "Start: " + DateTime.Now.ToString()
End Sub
Public Sub RaisePostBackEvent(ByVal eventArgument As String) _
Implements IPostBackEventHandler.RaisePostBackEvent
If Session("BackgroundThread") is Nothing Then
Exit Sub
End If
Dim t as Thread = CType(Session("BackgroundThread"), Thread)
If t.ThreadState = ThreadState.Stopped Then
ErrMsg.Text = "Done: " + DateTime.Now.ToString()
Session("BackgroundThread") = Nothing
Else
ErrMsg.Text = "Processing: " + DateTime.Now.ToString() + " - " + t.ThreadState.ToString()
End If
End Sub
</SCRIPT>
<HTML>
<HEAD>
<SCRIPT language="javascript">
//<!--
function onLoad()
{
if(<%= IIF(Session("BackgroundThread") is Nothing, "false", "true") %>)
{
toggleLoading();
setTimeout("<%= Page.ClientScript.GetPostBackEventReference(Me, "") %>", 10000);
}
}
function toggleLoading(){
document.getElementById('imgLoading').style.display = 'block';
setTimeout("document.images['imgLoading'].src='images/loading.gif'", 100);
}
// -->
</SCRIPT>
</HEAD>
<BODY OnLoad="onLoad();">
<FORM runat="server">
<ASP:Button runat="server" Text="Test" OnClick="Test" onClientClick="javascript: toggleLoading();" />
<ASP:Label runat="server" Id="ErrMsg" />
<IMG id="imgLoading" src="images/loading.gif" style="display: none;" />
</FORM>
</BODY>
</HTML>
Figured out my problem. Turns out deleting any folder in the ASP root folder will restart the application and reset all Session variables.
To get around that I added the following to my Application_OnStart method in Global.asax
Dim p As System.Reflection.PropertyInfo = GetType(HttpRuntime).GetProperty("FileChangesMonitor", Reflection.BindingFlags.Public Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Static)
Dim o As Object = p.GetValue(Nothing, Nothing)
Dim f As System.Reflection.FieldInfo = o.GetType.GetField("_dirMonSubdirs", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.IgnoreCase)
Dim monitor As Object = f.GetValue(o)
Dim m As System.Reflection.MethodInfo = monitor.GetType.GetMethod("StopMonitoring", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
m.Invoke(monitor, New Object() {})
The problems is that this is a background thread on the server that is sending the emails finishes but the response has already been sent to the user. When The user opens the page the background thread is started off, and the server returns with the response on the parent thread, the background thread is still running away on the server for sometime AFTER the response has already been sent
To achieve what you want you would need to have the page refreshing on a Javascript or some ajax to poll the server and keep check if this background thread has completed. ie the background thread is started, and the user is told that emails are being proccessed, 2 seconds later the page is automatically refreshed and the user is still told emails are being processed. Finally When all emails are sent the repeater is updated and automatic refresh is disabled
I have a CreateUserWizard control using forms authentication on my login/create user page. I customized the CreateUserWizardStep1 so that I could add some additional validators.
After successfully creating a user with the control and it displays "Complete
Your account has been successfully created." I have added an additional button that will allow the person to create another user by setting the ActiveStepIndex = 0. The problem is, while it sets the ActiveStepIndex correctly, it retains the old user account credentials. I try to clear them manually using the following code, but they still stick...Anyone have any ideas?
Protected Sub btnCreateAnotherUser_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Me.cuwMain.ActiveStepIndex = 0
CleanCreateNewUserInput()
End Sub
Private Sub CleanCreateNewUserInput()
Dim txtUserName As TextBox
txtUserName = FindControlIterative(Me.cuwMain, "UserName")
txtUserName.Text = String.Empty
Dim txtPassword As TextBox
txtPassword = FindControlIterative(Me.cuwMain, "Password")
txtPassword.Text = String.Empty
Dim txtConfirmPassword As TextBox
txtConfirmPassword = FindControlIterative(Me.cuwMain, "ConfirmPassword")
txtConfirmPassword.Text = String.Empty
Dim txtEmail As TextBox
txtEmail = FindControlIterative(Me.cuwMain, "Email")
txtEmail.Text = String.Empty
Dim txtQuestion As TextBox
txtQuestion = FindControlIterative(Me.cuwMain, "Question")
txtQuestion.Text = String.Empty
Dim txtAnswer As TextBox
txtAnswer = FindControlIterative(Me.cuwMain, "Answer")
txtAnswer.Text = String.Empty
End Sub
It finds the textboxes correctly, but it does not actually reset their values, even though in the debugger it says it did.
Thoughts ?
What happens if you call Response.Redirect(Request.Url.ToString(), true)? That should clear everything for you.
Also, the recursive nature of the FindControlIterative call would make your code quite expensive to run as it has to drill down into the control heirarchy for every control that you are looking for.
The problem with your code is that:
In a Wizard control, ViewState is not responsible for storing the modified values for controls such as TextBoxes. These controls implement the IPostBackDataHandler interface. The LoadPostBackData event fires in the page lifecycle, in which the VALUES of the controls load from the form HTTP POST headers... which are resubmitted by the client...
So how to destroy the HTTP POST Headers to clear the control values?
A new request results in new HTTP POST Headers... simply do this in the Button click event handler:
Response.Redirect(Page.Request.Url.ToString());
This has the added benefit that it goes to Step 1 of the wizard so you also dont have to do... wiz.MoveTo(wiz.WizardSteps[0]).
Credit to Konrad - ASP.Net Wizard - How to clear contents of web controls
I feel silly posting this..., but I just turned viewstate off on the CreateUserWizard control and that did it.
Thanks for the help Daniel, I now have a better understanding on how ASP.NET stores information.