GridView databinding twice on postbacks

J

J055

Hi

I have a very simple configuration of the GridView with paging and sorting.
When I do a postback the DataBinding event fires twice - in both the
ProcessPostData and PreRender stages of the page life cycle.
In this example the event fires twice when a) GridView EnableViewState=False
and any image type control in the <columns/> element. When either
EnableViewState is set to true or the image button is removed, the event
fires once. Please see the code below:

Webpage
----------
....
<form id="UserAccounts" runat="server">
<div>
<asp:GridView ID="UserGrid" runat="server" AllowPaging="True"
AllowSorting="True"
AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
OnDataBinding="UserGrid_DataBinding"
DataKeyNames="UserID" EnableViewState="False">
<Columns>
<asp:ButtonField ButtonType="Image" ImageUrl="~/images/Profile.gif"
Text="Permissions" />
<asp:BoundField DataField="UserID" HeaderText="UserID"
SortExpression="UserID" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$
ConnectionStrings:AccountsModule%>"
ProviderName="System.Data.SqlClient"
SelectCommand="usp_Accounts_GetAllUsers"
SelectCommandType="StoredProcedure"></asp:SqlDataSource>
</div>
</form>
....

CodeBehind (this is the only code in the page class)
----------------------------------------------------
....
protected void UserGrid_DataBinding(object sender, EventArgs e)
{
Trace.Warn("UserGrid_DataBinding");
}
....

Is there a way to stop this happening without having to EnableViewState?
This would add completely unnecessary overhead to the page.
Any suggestions/comments/workarounds will be very welcome.
Many thanks
Andrew



More background to this here:
http://groups.google.co.uk/group/mi...read/thread/48e3d4d143cd685f/487449f35f61bbf3
 
S

Steven Cheng[MSFT]

Hi Andrew,

Thank you for posting.

Seems you're still struggling with this problem. And from the description
in this thread, I noticed that you said the problem behavior occurs in the
following two cases:

1. GridView EnableViewState=False
=========================

This is an expected behavior when EnableViewState= false, because for
ASP.NET template datbound controls (such as DataGird,GridView,
DataList...), after databinding, the data and related nested control
properties are persisted in ViewState, so that when the page postback,
those info are get restored from viewstate without redo the databinding.
Howerver, when the ViewState is disabled, the runtime(Page) will do an
additional databinding, to repopulate the control structure and data before
process events.... This can explain the behavior of the event handler
executes twice.


2. Any image type control in the <columns/> element.
=========================

This is still the strange behavior I'm quite confusing. Based on my local
tests, an Imagebutton field won't cause additional databinding.

Does either of the above two cases (#1 and #2) can cause the databinding
problem individually?

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

J055

Hi Steven

This code does NOT cause databinding to fire twice on postbacks.

<asp:GridView ID="UserGrid" runat="server" AllowPaging="True"
AllowSorting="True"
AutoGenerateColumns="False" DataSourceID="SqlDataSource1"
OnDataBinding="UserGrid_DataBinding"
DataKeyNames="UserID" EnableViewState="False">
<Columns>
<asp:BoundField DataField="UserID" HeaderText="UserID"
SortExpression="UserID" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$
ConnectionStrings:AccountsModule%>"
ProviderName="System.Data.SqlClient"
SelectCommand="usp_Accounts_GetAllUsers"
SelectCommandType="StoredProcedure"></asp:SqlDataSource>


If I add this line to the above code then the event does fire twice.

<asp:ButtonField ButtonType="Image" ImageUrl="~/images/Profile.gif"
Text="Permissions" />

I don't want to make unnecessary connections to the database but I also
don't want to have a very large viewstate. What's the best way to deal with
this?

Thanks
Andrew
 
S

Steven Cheng[MSFT]

Thanks for your response Andrew,

So far I'm still feeling quite strange about the image button field
behavior, (the enableviewstate="false" case is expectable). Since I've also
tried the same test and failed to reproduce the same behavior, it'll also
be very hard to do some further throubleshooting since low level debugging
will also require a simplified reproduce demo. Anyway, if you still haven't
got any further clues on this issue, I would recommend you consider contact
the CSS for further troubleshooting.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.
 
S

sundna

Hi Steven,
i've same problem with gridview :'(.
Any event is fire 2 times if i set "EnableViewstate = true" or i use
an imagebutton in an itemtemplate.
I use an objectdatasource for gridview datasourceid.

Problem is "ViewState" but i can't disabled it :'((

Regards,

Mauro

Steven Cheng[MSFT] ha scritto:
 
S

Steven Cheng[MSFT]

Hi Mauro,

If all the events(including page events) get fire twice(and viewstate is
not disabled), I think it could be:

1. Event handler is registered twice (are you using C# or VB.NET) ?

2. The page is requested twice each time postback ( you can check the IIS
log to verify this).

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

sundna

Hi Steven,
thanks a lot for the answer
"all the events(including page events)"

not all of events are fire twice but only a gridview event.

i'm using C# and i'm sure that Event handler is registered one time.

I've checked the IISlog and my log and there are twice request when I
invoke update/insert/delete event on gridview.

I have noticed that second event fired don't have any information, for
example eventargs is null and on update event 2 times
EditIndex is set on -1.

also my friend has the same problem but he used this workaround
"imgEdit.OnClientClick = String.Concat("document.getElementById('",
imgEdit.ClientID, "').disabled=true;",
Page.ClientScript.GetPostBackEventReference(imgEdit, e.Item( 0
).ToString()))

he disabled a "onclick event " on image object

I think that the imagebutton is rendered as an "<input type=image>"
when u press an image, a _doPostback function start and also normal
submit of the page
the first one runs correctly but the second one generate the error in
fact my friend has disabled the
"client onclick" event handeler on image object.

by Mauro
 
S

Steven Cheng[MSFT]

Hello Andrew and Mauro,

After some further research, I think we may have encountered an issue of
the built-in ButtonField (which is set to "Image" type) in GridView
control. It is actually caused by the <input type="image"
onclick="__dopostback..." ..> tag generated by the built-in ButtonField(set
to Image type). In this tag, there are two things that will cause a click
on the image to trigger

a POST to the URL:
<input type="image" src="image.gif"
onclick="javascript:__doPostBack('GridView1','Delete$0')"
style="border-width:0px;"
/>

The INPUT element itself will cause a POST, and the script function
executed during
onclick will cause a POST.

I've seen our internal db recorded this issue. So far we may consider use
some workaround like below:
===========================================
One obvious workaround is to change the Button type to a Regular button or
a Link
Button.

If we want to use ImageButton, we can put it in a TemplateField. We may
need to
handle the Command event on the ImageButton and call the Delete method,
passing the
RowIndex as the CommandArgument, like this:

<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton runat=server id="ImageButton1" CommandName="Delete"
ImageUrl="..."
CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'
OnCommand="ImageButton1_Command" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>

protected void ImageButton1_Command(object sender, CommandEventArgs e) {
GridView1.DeleteRow(Int32.Parse(e.CommandArgument.ToString()));
}
==============================================

Hope this helps some. Sorry for the inconvenience if this is the issue that
trouble you.

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
J

J055

Hi Steven

These controls cause databinding to fire twice:

CommandField ButtonType="Image"
ButtonField ButtonType="Image"

ImageButton

I don't think your work around helps if you want to use an image. Any
suggestions?

Cheers
Andrew
 
S

Steven Cheng[MSFT]

Hi Andrew,

According to the <input type="image" onclick="__doPostBack....."/>
element's bebhavior, the page will be postback twice when the client user
click on such an image field in GridView. And each postback is a complete
request to server-side, that'll cause many events fires twice within the
page's server http pipeline. The workaround is acually try avoid using the
image field directly. but use a TemplateField with a Image button instead.
Such image button will be rendered as a html <input type="image" ..../>
without "onclick" event handler(client -side).

Regards,

Steven Cheng
Microsoft Online Community Support


==================================================

When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.

==================================================


This posting is provided "AS IS" with no warranties, and confers no rights.



Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
Joined
Sep 3, 2006
Messages
2
Reaction score
0
Sorting event fires twice - is the problem solved or any workaround

I have been having the same problem as this post. The GridView sorting event fires twice when i have an imagebuttuon in the columns of the Grid.

Is the problem solved or is there any workaround for this.
I would really appreciate all the help.
 
Joined
Jan 15, 2009
Messages
1
Reaction score
0
This is a quite old topic, but no final workaround posted, so I'll add my opinion :)

It's a known issue with GridView that if buttons with type image are used postback is fired twice.

I think the easiest workaround of this is to use CommandField with type Link (see below).

HTML:
<asp:CommandField 
  ShowEditButton="true" 
  ButtonType="Link" 
  ShowDeleteButton="true"
  EditText="<img src=Img/AccordWeb/Edit.gif alt='Edit assignment' border='0'>"
  DeleteText="<img src=Img/AccordWeb/delete.gif alt='Delete' border='0'>" 
  ControlStyle-CssClass="cursorPointer">
</asp:CommandField>

Hope that helps,
Wojciech Kucia
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top