Simple message to display on file upload - asp.net

I have been working on a file upload section within my ASP.NET site.
With the below code, I am able to get a user to upload documents based based on the Regular Expressions set within the RegularExpressionValidator. I am happy that this works accordingly.
What I would like to complete now is a message to indicate that the file has been uploaded successfully. I am unsure how to complete this, but would like to add it to a Label named "fileuploaded".
Here is my code for the .aspx page:
<table width = "60%">
<tr>
<td>Modes of Operation:</td>
<td>
<asp:FileUpload ID="FileUpload1" runat="server" />
</td>
<td>
<asp:Button ID="buttonUpload" runat="server" Text="Upload" ValidationGroup="FileUpload" />
</td>
</tr>
<tr>
<td colspan="3">
<asp:RequiredFieldValidator ID="FilenameRFValidator" runat="server"
ControlToValidate="FileUpload1" Display="Dynamic"
ErrorMessage="RequiredFieldValidator" ValidationGroup="FileUpload">
* Please select a file to upload...
</asp:RequiredFieldValidator></td>
</tr>
<tr>
<td colspan="3">
<asp:RegularExpressionValidator ID="FilenameRegExValidator" runat="server"
ControlToValidate="FileUpload1" Display="Dynamic"
ErrorMessage="RegularExpressionValidator"
ValidationExpression="(?i)^[\w\s0-9.-]+\.(txt|pdf|doc|docx|xls|xlsx)$"
ValidationGroup="FileUpload">
* Please upload file in format .pdf / .docx / .xlsx.
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
<asp:Label ID="lblfileuploaded" runat="server" Text=""></asp:Label>
And here is my code so far for the VB page:
Protected Function GetUploadList() As String()
Dim folder As String = Server.MapPath("~/Uploads")
Dim files() As String = Directory.GetFiles(folder)
Dim fileNames(files.Length - 1) As String
Array.Sort(files)
For i As Integer = 0 To files.Length - 1
fileNames(i) = "" & Path.GetFileName(files(i)) & ""
Next
Return fileNames
End Function
Protected Sub UploadThisFile(ByVal upload As FileUpload)
If upload.HasFile Then
Dim theFileName As String = Path.Combine(Server.MapPath("~/Uploads"), upload.FileName)
If File.Exists(theFileName) Then
File.Delete(theFileName)
End If
upload.SaveAs(theFileName)
End If
End Sub
Protected Sub buttonUpload_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles buttonUpload.Click
UploadThisFile(FileUpload1)
UploadedFiles.DataBind()
End Sub
Any help in advance is much appreciated.

As Tim Schmelter says in the comments, you should just set the text of the label after SaveAs has been successfully called.
You can use a Try -> Catch to make sure the there were no exceptions (according to the MSDN article linked above, the SaveAs method could throw an HttpException). Something like this:
Try
upload.SaveAs(theFileName)
fileuploaded.Text="File uploaded successfully"
Catch ex As Exception
fileuploaded.Text="Upload failed. Reason: " + ex.Message

Related

Any ideas why my FileUpload is showing no file?

I have a simple FileUpload box that is alble to accept files and save them to a location on a server on one web page, but the page I'm working on now has a form view inside of a radPageView, inside of a RadMultiPageView. When I attempt to see if there is a file in the FileUpload control, I am met with null values every time, eventhough I'm loading in a file. Here are some snippets of my code, trimmed down a little. Part of the problem is that in all of the tutorials I've found online, users are entering some of this information in the vb for the button click event, where I'm entering it in the xyz Handles .Updating section.
The prolem I run into is that when I get to the FileUpload1.HasFile it shows that there is no file, even if I have uploaded one. In fact, it shows Null, as if I haven't properly connected to the FileUpload control. I messed around with different ways to connect to the FileUpload control, but none of them really worked.
<telerik:RadMultiPage ID="RadMultiPage1" runat="server" SelectedIndex="0" CssClass="multiPage"
BorderColor="Black" BorderStyle="Solid">
<telerik:RadPageView ID="pvMemoDoc" runat="server">
<asp:FormView ID="fvMemoDoc" runat="server" DefaultMode="Edit" DataSourceID="dsMemos"
DataKeyNames="coreDocID">
<EditItemTemplate>
<table class="tblNoSpace">
[...Other Code...]
<%--Begin file upload section--%>
<tr>
<td class="fieldLabel">File to upload:<br />
</td>
<td>
<asp:FileUpload ID="FileUpload1" runat="server" Width="600" ToolTip="Browse for file" />
</td>
</tr>
<tr>
<td colspan="2" style="text-align: right">
<asp:Label ID="lblFU1" runat="server" Enabled="false" Visible="false"
Text="(only select new file if you wish to replace existing file)"></asp:Label>
</td>
</tr>
<tr>
<td>
<br />
<br />
<asp:Button ID="btnUpdateMemo" CommandName="Update" runat="server" Text="Update Memo"
CausesValidation="true" ValidationGroup="MemoInformation"
ToolTip="Save updates" />
</td>
</tr>
</table>
</EditItemTemplate>
</asp:FormView>
</telerik:RadPageView>
[...Other Code...]
</telerik:RadMultiPage>
VB Code:
Private Sub DsMemo_Updating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.SqlDataSourceCommandEventArgs) Handles dsMemos.Updating
Dim FileUpload1 As FileUpload = CType(fvMemoDoc.FindControl("FileUpload1"), FileUpload)
'Dim FileUpload1 As FileUpload = CType(fvMemoDoc.Controls(0).Controls(0).FindControl("FileUpload1"), FileUpload)
'Dim FileUpload1 As FileUpload = CType(fvMemoDoc.Controls(0).FindControl("FileUpload1"), FileUpload)
'Dim FileUpload1 As FileUpload = TryCast(updateButton.Parent.Parent.FindControl("FileUpload1"), FileUpload)
If FileUpload1.HasFile Then
[...Other Code Here..]
[...Never gets past FileUpload1.HasFile...]
End If
End Sub
It appears after some tinkering that there was an issue with modify versus read/write permissions.
The way that control was working is that it would store a temporary file and then delete it off of the server, so that is why no file was showing.
Giving the web app modify access to the folder where the temporary files are stored solved my issue.

Trigger confirmation message box during asp.net LoggingIn event

I have a web application in vb in which I am using this approach to prevent a user from having concurrent logins due to a simple licensing agreement.
It works great, if a user logs in with an account that is already in use, the first user gets logged out. I am trying to add a messagebox or some kind of js confirmation box in the loggingin event that states:
This user account has been active in the last 20 minutes.
If someone else is using it, then logging in may possibly
compromise any report generation or activity.
Continue login?
Here is the code:
<asp:Login ID="Login1" runat="server" DestinationPageUrl="~/Dashboard/Default.aspx" >
<LayoutTemplate>
<table border="0" cellpadding="0">
<tr>
<td align="right"><p><asp:Label ID="UserNameLabel" runat="server" AssociatedControlID="UserName">User Name:</asp:Label></p></td>
<td align="right">
<p><asp:TextBox ID="UserName" runat="server" Width="220" autocomplete="on" />
<asp:RequiredFieldValidator ID="UserNameRequired" runat="server" ControlToValidate="UserName" Text="*"
ErrorMessage="User Name is required." ToolTip="User Name is required." ValidationGroup="Login1" /></p>
</td>
</tr>
<tr>
<td align="right"><p><asp:Label ID="PasswordLabel" runat="server" AssociatedControlID="Password">Password:</asp:Label></p></td>
<td align="right">
<p><asp:TextBox ID="Password" runat="server" TextMode="Password" Width="220"></asp:TextBox>
<asp:RequiredFieldValidator ID="PasswordRequired" runat="server" ControlToValidate="Password" Text="*"
ErrorMessage="Password is required." ToolTip="Password is required." ValidationGroup="Login1" /></p>
</td>
</tr>
<tr>
<td align="center" colspan="2" style="color: red"><asp:Literal ID="FailureText" runat="server" EnableViewState="False"></asp:Literal></td>
</tr>
<tr>
<td align="right" colspan="2"><asp:LinkButton CssClass="prettyButton" ID="LoginButton" runat="server" CommandName="Login" Text="Log In" ValidationGroup="Login1" /></td>
</tr>
</table>
</LayoutTemplate>
</asp:Login>
Private Sub Login1_LoggingIn(sender As Object, e As LoginCancelEventArgs) Handles Login1.LoggingIn
Dim messagetext As String = "This user account has been active in the last 20 minutes." + Environment.NewLine + Environment.NewLine
messagetext += "If someone else is using it, then logging in may possibly" + Environment.NewLine
messagetext += "compromise any report generation or activity." + Environment.NewLine + Environment.NewLine
messagetext += "Continue login?"
Dim userNameTextBox As System.Web.UI.WebControls.TextBox = DirectCast(Login1.FindControl("UserName"), System.Web.UI.WebControls.TextBox)
Dim currentUser As MembershipUser = Membership.GetUser(userNameTextBox.Text)
If currentUser IsNot Nothing Then
If currentUser.IsOnline Then
'*****CONFIRMATION MESSAGE BOX TO GO HERE*****/
Dim result = MessageBox.Show(messagetext , "Login Warning", MessageBoxButtons.YesNo)
'* IF USER DECIDES NOT TO LOGIN:*/
If result = DialogResult.No Then
e.Cancel = True
End If
'* ELSE LOGIN CONTINUES AND ORIGINAL USER IS LOGGED OUT*/
End If
End If
End Sub
Private Sub Login1_LoggedIn(sender As Object, e As EventArgs) Handles Login1.LoggedIn
Dim userNameTextBox As System.Web.UI.WebControls.TextBox = DirectCast(Login1.FindControl("UserName"), System.Web.UI.WebControls.TextBox)
SingleSessionPreparation.CreateAndStoreSessionToken(userNameTextBox.Text)
End Sub
Now, I can use a windows form msgbox() locally, and everything works great, but once I put it on a server, the message box obviously doesn't work. I've tried ClientScript and ScriptManager, but the client side check doesn't seem to get triggered.
Any help is greatly appreciated.
Do not use the VB MessageBox in a web site. It will ONLY show up on the server - and will more than likely kill your page every time. The end user will never see it on his browser.
There are a bunch of ways you could handle what you're trying to achieve, though one that will work well is to show the user a javascript confirm box; which is more or less the same as a message box but has an OK and Cancel button instead.
You can show this to the user by injecting a little javascript to your page as it renders. So, remove your Dim result.... line and replace it with something like this: - this will inject some javascript to your pages HTML.
Dim cs As ClientScriptManager = Page.ClientScript
cs.RegisterStartupScript(Me.GetType(), "userChecker", "UserCheck(Confirm('yourMessage'));", True)
NOTE - you will also remove the code that checks your dialog, I.E If result = ....
When the page loads the confirm dialog will appear. The captured response, in this case, will be passed to a javascript function called UserCheck - so have a javascript function in your HTML to accept it. Something like this:
function UserCheck(t){
if (t){
// do something for OK
}else{
// do something for CANCEL
}
Within the UserCheck you can easily handle the users response. Perhaps by redirecting, or causing a postback by calling the __doPostBack function of .Net.

Accessing button in repeater control

I'm trying - quite unsuccessfully - to access a button inside a repeater control. I have a repeater set up on a page that displays movies that are currently showing in cinemas. I have created two buttons and added them to the repeater - one for trailer and another for review. For the review I want to link to another page which will have another repeater with paging enabled. When a users clicks the review button they should be brought to a page that shows only the reviews for that specific movie. This is that code I have:
MARKUP:
The repeater:
<asp:Repeater ID="movies" runat="server">
<ItemTemplate>
<table width="641px">
<tr>
<td>
<span style="font-weight:bold;font-size:16px;">
<%# Container.DataItem("MovieTitle")%>
</span>
</td>
<td>
<span style="float:right;">
<asp:Image ID="Image1" runat="server" ImageUrl = '<%# Eval("Total")%>' style="width:80px;height:14px;"/>
</span>
</td>
</tr>
<tr>
<td colspan="2">
<hr style="height:1px;border-bottom:none;color:#e3e3e3;"/>
</td>
</tr>
</table>
<table width="641px">
<tr>
<td>
<asp:Image ID="Image2" runat="server" ImageUrl = '<%# Eval("MovieImageFileName")%>' style="width:180px;height:108px;border:1px solid #e3e3e3;"/>
</td>
<td style="vertical-align:top;">
<%# Container.DataItem("Synopsis")%>
</td>
</tr>
</table>
<table width="641px">
<tr>
<td>
<span style="float:right">
<asp:Button ID="btnTrailer" runat="server" Text="Trailer" BackColor="#FF9900" ForeColor="White" />
<asp:Button ID="btnReview" runat="server" Text="Review" BackColor="#FF9900" ForeColor="White" CommandName="Review" />
</span>
</td>
</tr>
<tr>
<td>
<hr style="height:1px;border-bottom:none;color:#e3e3e3;"/>
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
CodeBehind:
Dim movie_title As String
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim myConn As New OleDbConnection
Dim cmd As New OleDbCommand
Dim dr, aDataReader As OleDbDataReader
Dim query, movieID As String
movie_title = Request.QueryString("id")
myConn = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source = " & _
Server.MapPath("/App_Data/MovieBoard.accdb"))
myConn.Open()
Dim sqlQuery = "Select movieID From Movies"
Dim aCmd = New OleDbCommand(sqlQuery, myConn)
aDataReader = aCmd.ExecuteReader()
If aDataReader.Read() = True Then
movieID = aDataReader(0)
Else
movieID = "0"
End If
query = ("Select MovieTitle, Genre, Synopsis, Starring, Total, Director, MovieImageFileName From Movies, MovieReviews, MReviewRatings WHERE Movies.MovieID = MovieReviews.MovieID AND MovieReviews.MReviewID = MReviewRatings.MReviewID AND ReviewerTypeID = 1")
cmd = New OleDbCommand(query, myConn)
dr = cmd.ExecuteReader()
movies.DataSource = dr
movies.DataBind()
End Sub
Protected Sub movies_ItemCommand(source As Object, e As RepeaterCommandEventArgs) Handles movies.ItemCommand
If e.CommandName = "Review" Then
Response.Redirect("testingreviews.aspx?id = '" & movie_title)
End If
End Sub
When I run page the page displays but when I click the review button I get the following error:
Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/>
in configuration or <%# Page EnableEventValidation="true" %> in a page. For security purposes, this feature verifies that arguments to postback or
callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.
RegisterForEventValidation method in order to register the postback or callback data for validation.
Anyone any ideas on what I am doing wrong? I am very new to asp.net.
If you want to access a button use the event ItemCreated or maybe its ItemDataBound.
Handles movies.ItemCreated
In that event you can then refeer to the button using FindControl,
Something like this
Sub Movies_ItemDataBound(Sender As Object, e As RepeaterItemEventArgs) Handles movies.ItemDataBound
Dim Btn As Button = CType(e.Item.FindControl("ButtonName"),Button)
End Sub

Getting the 'Object reference not set to an instance of an object' error..vb

I don't undertand why I'm getting this error, code was working and running perfectly earlier. I was trying to update the user's email via button. It worked fine but now for some reason it keeps giving me the error:
"Object reference not set to an instance of an object.
Line 34: EmailTextBox.Text = u.Email"
Been scratching at this for a couple of hours now, anyone have an idea what it might be?
My aspx.vb code is:
Public Class _Default
Inherits System.Web.UI.Page
Dim u As MembershipUser
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
u = Membership.GetUser(User.Identity.Name)
If Not IsPostBack Then
EmailTextBox.Text = u.Email
End If
End Sub
Public Sub UpdateEmailButton_OnClick(ByVal sender As Object, ByVal args As EventArgs)
Try
u.Email = EmailTextBox.Text
Membership.UpdateUser(u)
Msg.Text = "User e-mail updated."
Catch e As System.Configuration.Provider.ProviderException
Msg.Text = e.Message
End Try
End Sub
aspx code:
<h3>Update E-Mail Address for <%=User.Identity.Name%></h3>
<asp:Label id="Msg" ForeColor="maroon" runat="server" /><br />
<table cellpadding="3" border="0">
<tr>
<td>E-mail Address:</td>
<td><asp:TextBox id="EmailTextBox" MaxLength="128" Columns="30" runat="server" /></td>
<td><asp:RequiredFieldValidator id="EmailRequiredValidator" runat="server"
ControlToValidate="EmailTextBox" ForeColor="red"
Display="Static" ErrorMessage="Required" /></td>
</tr>
<tr>
<td></td>
<td><asp:Button id="UpdateEmailButton"
Text="Update E-mail"
OnClick="UpdateEmailButton_OnClick"
runat="server" /></td>
</tr>
</table>
you need into to the debugging model and see the u = Membership.GetUser(User.Identity.Name) whether is null.
i guess the Membership.GetUser(User.Identity.Name) return null. may be your logged was timeout,may be just MembershipUser occure error.

How do I best populate an HTML table in ASP.NET?

This is what I've got. It works. But, is there a simpler or better way?
ASPX Page…
<asp:Repeater ID="RepeaterBooks" runat="server">
<HeaderTemplate>
<table class="report">
<tr>
<th>Published</th>
<th>Title</th>
<th>Author</th>
<th>Price</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><asp:Literal ID="LiteralPublished" runat="server" /></td>
<td><asp:Literal ID="LiteralTitle" runat="server" /></td>
<td><asp:Literal ID="LiteralAuthor" runat="server" /></td>
<td><asp:Literal ID="LiteralPrice" runat="server" /></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
ASPX.VB Code Behind…
Protected Sub Page_Load( ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim db As New BookstoreDataContext
RepeaterBooks.DataSource = From b In db.Books _
Order By b.Published _
Select b
RepeaterBooks.DataBind()
End Sub
Sub RepeaterBooks_ItemDataBound( ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles RepeaterBooks.ItemDataBound
If e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem Then
Dim b As Book = DirectCast(e.Item.DataItem, Book)
DirectCast(e.Item.FindControl("LiteralPublished"), Literal).Text = "<nobr>" + b.Published.ToShortDateString + "</nobr>"
DirectCast(e.Item.FindControl("LiteralTitle"), Literal).Text = "<nobr>" + TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Title)) + "</nobr>"
DirectCast(e.Item.FindControl("LiteralAuthor"), Literal).Text = "<nobr>" + TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Author)) + "</nobr>"
DirectCast(e.Item.FindControl("LiteralPrice"), Literal).Text = "<nobr>" + Format(b.Price, "c") + "</nobr>"
End If
End Sub
Function TryNbsp(ByVal s As String) As String
If s = "" Then
Return " "
Else
Return s
End If
End Function
#Geoff
That sort of Eval statement was actually added in 2.0, but if performance is important Eval should be avoided since it uses Reflection.
The repeater is a pretty good way of doing it, although it might be faster to generate the table in code:
ASPX Page:
<table class="report" id="bookTable" runat="server">
<tr>
<th>Published</th>
<th>Title</th>
<th>Author</th>
<th>Price</th>
</tr>
</table>
Code Behind:
Protected Sub Page_Load( ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostback Then
BuildTable()
End If
End Sub
Private Sub BuildTable()
Dim db As New BookstoreDataContext
Dim bookCollection = from b in db.Books _
Order By b.Published _
Select b
Dim row As HtmlTableRow
Dim cell As HtmlTableCell
For Each book As Books In bookCollection
row = New HtmlTableRow()
cell = New HtmlTableCell With { .InnerText = b.Published.ToShortDateString }
row.Controls.Add(cell)
cell = New HtmlTableCell With { .InnerText = TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Title)) }
row.Controls.Add(cell)
cell = New HtmlTableCell With { .InnerText = TryNbsp(HttpContext.Current.Server.HtmlEncode(b.Author))
row.Controls.Add(cell)
cell = New HtmlTableCell With { .InnerText = Format(b.Price, "c") }
row.Controls.Add(cell)
bookTable.Controls.Add(row)
Next
I guess it depends on how important speed is to you. For simplicity's sake I think I would go with the Repeater.
The ListView control introduced with framework 3.5 might be a little bit better solution. Your markup would look like this:
<asp:ListView runat="server" ID="ListView1"
DataSourceID="SqlDataSource1">
<LayoutTemplate>
<table runat="server" id="table1" runat="server" >
<tr runat="server" id="itemPlaceholder" ></tr>
</table>
</LayoutTemplate>
<ItemTemplate>
<tr runat="server">
<td runat="server">
<asp:Label ID="NameLabel" runat="server"
Text='<%#Eval("Name") %>' />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
You'll want to set your data source ID from a public or private property in the code-behind class.
In .Net 3.0+ you can replace your ItemDataBound to the asp:Literal by doing something like this:
<ItemTemplate>
<tr>
<td><%# Eval("published") %></td>
...
where "published" is the name of a field in the data you have bound to the repeater
Edit:
#Alassek: I think the performance hit of reflection is often over-emphasized. Obviously you need to benchmark performance of your app, but the hit of the Eval is likely measured in milliseconds. Unless your app is serving many concurrent hits, this probably isn't an issue, and the simplicity of the code using Eval, along with it being a good separation of the presentation, make it a good solution.
This is what the GridView is for.
<asp:GridView runat="server" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField HeaderText="Published" DataField="Published" />
<asp:BoundField HeaderText="Author" DataField="Author" />
</Columns>
</asp:GridView>
I would use a GridView (or DataGrid, if you are using an older version of ASP.NET).
<asp:GridView ID="gvBooks" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField HeaderText="Published" DataField="Published" />
<asp:BoundField HeaderText="Title" DataField="Title" />
<asp:BoundField HeaderText="Author" DataField="Author" />
<asp:BoundField HeaderText="Price" DataField="Price" />
</Columns>
</asp:GridView>
With some code-behind:
Private Sub gvBooksRowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles gvBooks.RowDataBound
Select Case e.Row.RowType
Case DataControlRowType.DataRow
''' Your code here '''
End Select
End Sub
You can bind it in a similar way. The RowDataBound event is what you need.
I agree with Geoff, the only time we use Literals is if we want to do something different with the data.
For example, we might want a DueDate field to say "Today" or "Yesterday" instead of the actual date.
ALassek wrote:
…generate the table in code…
I like the look of that! It seems MUCH less likely to produce a run-time exception due to a typo or field name change.
If you don't need ASP.NET handled edit cabilities I would stay away from the DataGrid and the GridView ... they provide unnecessary bloat.

Resources