Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

why does a browser page refresh add another record 1

Status
Not open for further replies.

bookouri

IS-IT--Management
Feb 23, 2000
1,464
0
0
US
This page is not pretty. I'm working on ways to get "photos" into an image column so I'm just hacking around with this page. This page has two buttons. One button Adds a new person and their photo, the other button will modify a person who already exists and replace their existing photo. But, what I can NOT figure out is that after I click the button to add a person and then refresh the page to see the results in the grid, the page does NOT refresh the grid, but it DOES add a second record. And every time i refresh the page it will add another record. Can anybody tell me what I'm doing wrong so the page refresh "re-executes" the on_click event code without anybody clicking the button? I would like for the page to re-load the grid with the updated data every time the button is pressed and clear everything out so duplicate data is not added. But I can NOT figure out what is going on here.


<code>
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data.SqlClient"%>
<%@ Import Namespace="System.Data"%>
<%@ Import Namespace="System.IO "%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "
<script runat="server">

String GetUrl(Object name)
{
return "getphoto.aspx?name=" + name.ToString();
}

protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{

}
protected void Button1_Click(object sender, EventArgs e)
{
Stream imagestream;

int len = FileUpload1.PostedFile.ContentLength; // get length of the file
imagestream = FileUpload1.PostedFile.InputStream; // get stream for the image
Byte [] imagecontent = new Byte[len]; // create an array of bytes to hold image data
imagestream.Read(imagecontent, 0, len); // read image into array

SqlConnection con = new SqlConnection("Data Source=dev1\\sqlexpress;Initial Catalog=web;uid=write_images;password=write_images");
con.Open();
SqlCommand cmd = new SqlCommand("update persons set photo =(@photo) where name=@name",con);
cmd.Parameters.Add("@name", SqlDbType.VarChar, 20).Value = TextBox1.Text;
cmd.Parameters.Add("@photo", SqlDbType.Image).Value = imagecontent;
cmd.ExecuteNonQuery(); // insert
con.Close();
TextBox1.Text = "";
cmd.Parameters.Clear();

Response.Write("Person Modified Successfully");
}

protected void Button2_Click(object sender, EventArgs e)
{
{
Stream imagestream;

int len = FileUpload1.PostedFile.ContentLength; // get length of the file
imagestream = FileUpload1.PostedFile.InputStream; // get stream for the image
Byte[] imagecontent = new Byte[len]; // create an array of bytes to hold image data
imagestream.Read(imagecontent, 0, len); // read image into array

SqlConnection con = new SqlConnection("Data Source=dev1\\sqlexpress;Initial Catalog=web;uid=write_images;password=write_images");
con.Open();
SqlCommand cmd = new SqlCommand("insert into persons values (@name,@photo,null)", con);
cmd.Parameters.Add("@name", SqlDbType.VarChar, 20).Value = TextBox1.Text;
cmd.Parameters.Add("@photo", SqlDbType.Image).Value = imagecontent;
cmd.ExecuteNonQuery(); // insert
con.Close();
TextBox1.Text = "";
cmd.Parameters.Clear();
Response.Write("Person Added Successfully");
}
}
</script>

<html xmlns=" >
<head runat="server">
<title>Modify Photo</title>
</head>
<body>
<h2>Modify Photo</h2>
<form id="form1" runat="server">
<div>
<table>
<tr>
<td>Person Name
</td>
<td>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>Person's Photo
</td>
<td>
<asp:FileUpload ID="FileUpload1" runat="server" />
</td>
</tr>
</table>
<p />
<asp:Button ID="Button1" runat="server" Text="Modify Photo"
OnClick="Button1_Click" />
<asp:Button ID="Button2" runat="server" onclick="Button2_Click"
Text="Add Photo" Width="115px" />
<p />
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl="persons.aspx">Show Persons</asp:HyperLink>
</div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
BackColor="White" BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px"
CellPadding="3" DataKeyNames="image_id" DataSourceID="SqlDataSource1"
ForeColor="Black" GridLines="Vertical" Width="547px">
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:BoundField DataField="name" HeaderText="name" SortExpression="name" />
<asp:BoundField DataField="image_id" HeaderText="image_id"
InsertVisible="False" ReadOnly="True" SortExpression="image_id" />
<asp:BoundField DataField="person_id" HeaderText="person_id"
SortExpression="person_id" />
<asp:TemplateField HeaderText="Photo">
<ItemTemplate>
<asp:Image ID="Image1" ImageUrl='<%# GetUrl(Eval("name"))%>' runat="server" Width="100" Height="100"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCCCC" />
<HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F1F1F1" />
<SortedAscendingHeaderStyle BackColor="#808080" />
<SortedDescendingCellStyle BackColor="#CAC9C9" />
<SortedDescendingHeaderStyle BackColor="#383838" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:webConnectionString %>"
SelectCommand="SELECT * FROM [persons] ORDER BY [name], [image_id]">
</asp:SqlDataSource>
</form>
</body>
</html>



</code
 
... what I can NOT figure out is that after I click the button to add a person and then refresh the page ...
What do you mean by refresh the page? Are you using the browser buttons to refresh the page, or doing it in code?
 
just hitting the browser refresh button
 
That's the issue. By hitting the browser refresh button you are reposting the data and causing another insert. In the click of the button, requery the DB and get the data and rebind your grid so you can verify the data has been inserted.
 
What is throwing me off i guess is that in the click events the connection is being closed so I thought that would prevent anything else from happening. The button opens the connection and the button closes the connection. I didn't think the click event code could still be there somewhere in "memory" and able to be run again in the refresh event. I'll work from there and see if I can fix it..

thanks

 
when you refresh the page it's submit the previous request (which was clicking the button). The server picks this up request. spins up the webforms page. walks through the page lifecycle. detects the button was clicked and executes the code.

it's possible to see this using trace messages and stepping through the code. also understanding the webforms page life cycle would help to understand why this is happening.

there is a common approach to web development which resolves this. it's referred to as [tt]post, redirect, get[/tt].
1. when modifying data send as a http post
2. after modifying the data have the request redirect to uri
3. this redirect can use a http get instead of a http post

webforms sort of breaks down here, and certainly doesn't encourage this practice, but you can make it work. after completing the operation redirect the page back to itself.

so if you form is named "Foo.aspx"
Code:
//within the button click event
SavePicture(image file);
Response.Redirect("Foo.aspx", false);
then if the user clicks refresh the last request made was GET Foo.aspx (not POST Foo.aspx)

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
You can't "fix" it. The refresh button of the browser will always be available to the user and will always repost form data. The best way to avoid the issue is like I said before. After you insert your data, requery the database to get the rows from the table, and then rebind to the grid, or whatever. Now, if the user hits the refresh button, it will only requery the DB and rebind the grid, NOT insert another row.
 
Actually my suggestion will not work. You will have to do a redirect as Jason suggested.
 
I added a response.redirect("mypage.aspx",false);
and now everything works exactly like i wanted except.. when I ADD a photo, the refreshed page displays the new photo from the db perfectly, but the mod button does not cause the displayed photo to change to the new photo. When I "modify" a photo, the page redirects but the old photo is still displayed. The "modified" photo IS stored in the db and if I just hit the browser refresh button the "modified" photo is displayed, but it requires that manual page refreshing. Any idea how to change that behavior?

thanks
 
caching? either by asp.net or the browser.
asp.net cache you would need to configure. the browser will cache html/css/js/images locally to improve load times. this is by design.

other than that your code and workflow is sound.

Jason Meckley
Programmer

faq855-7190
faq732-7259
 
has to be caching, I just dont know yet how to get around it.
 
adding

<%@ OutputCache Duration="1" Location="None" %>

to the getphoto.aspx page fixes my problem

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top