Hello again,
I have run into another problem, this time one that seems to be pure CSLA related, so maybe you can help me out with this one.
I am still working on a Gridview that is using a CSLADataSource. I have the Edit Button Auto-generated, but I define the columns myself and have turned of Autogenerate Columns. When I click on the Edit button the selected row of the grid goes into Edit mode as expected and I can change the fields I have enabled. So far so good, but then things go wrong.
When I click the update button after I am done editing, the OnUpdate handler never gets called. I have stepped thru the code using the debugger to make sure the Update handler does not get called and indeed it does not. Instead the Onselect handler is called and the page goes make to "none edit" mode, displaying the old data in the row I just changed so my chaanges are lost. When I click Update the execution sequence goes like this:
The PageLoad event handler is called, but it does nothing because I wrote the code to initialize the form only when IsPostBack is false. Since IsPostBack is true when I click the Update button, the page load event handler just returns. The next method to be called is the OnSelect Event handler and that method loads the data to the grid, from a session object if that exists or from the database. I do this, so that I can load the grid when the page is displayed for the first time. When IsPostBack is true, I call DataBind on the GridView which in turn calls the OnSelect event Handler and I load the data in that handler. I am following the ProjectTracker example code, so most of this should sound very familiar to you.
Anyway, back to the update stuff. So I click Update Page_Load is called and does nothing, and then the Onselect handler is called which load data from the session object and returns. That's it. I am back in my form and the grid has been reloaded with the original data. My changes are lost and since the update handler was never called, nothing was saved either.
Can you explain to my why this is happening? Why is the Onselect Handler called when I clicked Update? It seems to me that the onselect handler not only wipes out my changes on the screen but it also clears the update event, though I don't understand why. Shouldn't the update handler becalled BEFORE the select handler is called? Do I need to test someplace to see if changes where made and prevent the OnSelect handler from updating the grid with data from the session? I don't see anything like that in the project tracker example code, but I am willing to try almost anything at this point.
I use a BusinessListBase object for my data. The List contains the data I need for the form and a childobject that is also a BusinessListBase that contains the data for the grid. I assign the child list to the CSLA dataSource ID which is assigned to the gridview's dataSource Id, thus binding the child list to the GridView. As far as I can see there is no functional difference between my code and the ProjectTracker example when it comes to how the data is loaded to the page initially, what the OnSelect handler does, and what the update handler does, yet my code does not work as expected.
I can post code if need be, but it would take considerable effort to cut that down to the bare necessities.
Any help would be greatly appreciated. TIA.
URW.
I don't know - this is a very common scenario and is known to work just fine, so there's something different about what you are doing somewhere.
You set the grid control's key value property so the grid knows the key value to pass through?
Yes I do. My list is set to dirty as well,
and yet the Select handler is called but not the update handler. In my search
for the problem, I have discovered my RowDataBound handler is called right
after the Select handler and it is the RowDataBound handler that my changes are
lost, which sort of makes sense since that is when the CSLA Object is bound to
the GridView. I also discovered that the Select handler is getting the data
from Session, so I am not calling the Data_fetch routine more than once. Finally,
once I click update I am stuck in Update mode. I have to click Cancel or Edit
on another row to get out of Update mode.
I have another person more familiar with
CSLA DataSource and editable GridViews looking at the code and he can’t
find what I am doing wrong either. My supervisor, who has been helping me with
this, has found some issues in my CSLA Business objects, but even after I made
those changes the problem continues. To be honest, I am not convinced it is in
the CSLA object. After all the debugging I have done, I am actually more
suspicious of .NET and right now I am rebuilding the form to see if that will
fix it. It would not be the first time that I, and others around here, have had
a form “misbehaving” for no reason and the way to fix it was to
rebuild the form.
I am not sure if any of this helps and I
appreciate your email and effort to help me out. If you have any suggestions, I
would like to hear them. Meantime, I will rebuild the form and see what that
does for me. If I find the problem, I will let you know if you like.
Thanks
Ute R. Willmore
ext. 4128
From: RockfordLhotka
[mailto:cslanet@lhotka.net]
Sent: Tuesday, June 24, 2008 12:09
AM
To: Willmore, Ute
Subject: Re: [CSLA .NET]
OnUpdateObject EventHandler not called
I don't
know - this is a very common scenario and is known to work just fine, so
there's something different about what you are doing somewhere.
You set
the grid control's key value property so the grid knows the key value to pass
through?
I am now finished with the re-creation of
my form but I am right back to square one. The OnUpdateObject handler is still
not getting called no matter how many times I make changes and click Update.
Instead the OnSelectHandler gets called, which gets the old data from session
and assigns it to the grid overwriting the data on the screen.
I tried assigning RowUpdating and
RowUpdated handlers to the grid rows thinking I could maybe use them to work
around this, but those are not getting called either. I am not sure, but
perhaps that is a function of the CSLA DataSource. At least it would make sense
in a way if using the CSLA DataSource would prevent the Grid Row Update
handlers from firing. Then again, maybe it is just another symptom.
At this point I am under instruction to
find a different way to get the page working. I have been stuck on this for 4 days
now, and my supervisor needs me to move on. Perfectly understandable since
neither he nor I are making any kind of headway with this.
But I thought I’d post my grid and
CSLA DataSource definition, just in case someone sees something that is wrong
and I can still get it fixed. Even if I can’t fix this one I am still
curious to know where I screwed up, so I can avoid the same mistake in the
future. So here are the definitions:
<asp:GridView
ID="EnrollmentOrderProductGridview" runat="server" AutoGenerateColumns="False"
AutoGenerateEditButton="True" DataKeyNames="EnrollmentID,ItemNumber" DataSourceID="EnrollmentOrderProductDataSource"
OnRowUpdated="EnrollmentOrderProductGridView_RowUpdated"
OnRowUpdating="EnrollmentOrderProductGridview_RowUpdating"
OnRowDataBound="EnrollmentOrderProductGridview_RowDataBound">
<Columns>
.
.
.
</Columns>
</asp:GridView>
<csla:CslaDataSource ID="EnrollmentOrderProductDataSource"
runat="server"
TypeName="My.Library.Customer.RepeatingOrders.EnrollmentOrderProductList"
TypeAssemblyName="My.Library"
TypeSupportsPaging="False" TypeSupportsSorting="False"
OnUpdateObject="EnrollmentOrderProductDataSource_UpdateOrderProduct"
OnSelectObject="EnrollmentOrderProductDataSource_SelectOrderProduct">
</csla:cslaDataSource>
I left out the column definitions for the grid since I did not think
they were critical. They do include definitions for the Key data items EnrollmentID
and ItemNumber though.
If you notice anything that is incorrect
please let me know.
Thanks
URW
From: RockfordLhotka
[mailto:cslanet@lhotka.net]
Sent: Tuesday, June 24, 2008 12:09
AM
To: Willmore, Ute
Subject: Re: [CSLA .NET]
OnUpdateObject EventHandler not called
I don't
know - this is a very common scenario and is known to work just fine, so
there's something different about what you are doing somewhere.
You set
the grid control's key value property so the grid knows the key value to pass
through?
> I am not sure, but perhaps
that is a function of the CSLA DataSource.
I won’t discount this
possibility. However, the CslaDataSource doesn’t actually _do_
very much if you look at it. It relies on the data binding infrastructure to
call the right operation.
In other words, while I can’t
say it won’t fail – you can look at the code yourself and see that
there are few (if any) possible points of failure in the runtime part of the
code…
Odds are far better that the data
binding infrastructure just isn’t calling the method in the control.
Here’s the code from the
control:
protected
override int ExecuteUpdate(IDictionary keys, IDictionary values, IDictionary
oldValues)
{
//
tell the page to update the object
UpdateObjectArgs args = new UpdateObjectArgs(keys, values, oldValues);
_owner.OnUpdateObject(args);
return args.RowsAffected;
}
It just raises the event –
so it is most likely the case that the data binding infrastructure isn’t
calling ExecuteUpdate()…
The only other possibility I can
think of is that CanUpdate() is somehow returning false. That might prevent
data binding from trying to do the update, because the control would be saying
it isn’t possible. That is unlikely, but I suppose could be the case. You
can test that by putting some code in your UI to display the CanUpdate value
from the control.
Rocky
Rocky,
I found the code for the ExecuteUpdate method, and put a break point in it. Sure enough, it never gets called, which tells us what we suspected already: The updateObject handler is not getting called because the handler is not assigned.
I tried to check the value of CanUpdate but I could not find it. None of the objects show that property when I stopped execution in the OnSelectObject Handler, which initialized my business list object and assigned it to e.BusinessObject in the handler. I checked the GridView object, and my business objects but I don't see that propert anywhere except in your code. I put a break point in the CanUpdate Get but it never gets called as far as I can tell. Can you perhaps help me out and give me a hint on where to find CanUpdate? I am using VS2005 and CSLA 214.
I also got to thinking about the CanUpdate property. So where is CanUpdate set? Would that be in the Authorization code? I am wondering if the whole issue could be caused by my not using the Authorization stuff at all. I control who can gets to the application by network login and Active Directory group, so I don't have to worry about someone trying to update who is not allowed to do so. Anyone who can access the app is allowed to update and those who can't update can't access the app. Every example I see for the CSLA DataSource uses Authorization rules though, except for my application.
So what do you think, is it possible that I am causing this problem by not applying authorization rules?
Thanks for the help.
Ute
Maybe you can't get to CanUpdate - I've never really tried. It isn't intended for use by a page developer, just by data binding.
But if you put a breakpoint there and it didn't get hit, that seems to imply that data binding never even tries to do the update - it never checks to even see if it is possible, so it must not have gotten that far...
Can you create a small test app that replicates the problem?
I am not sure if I can reduce the code to
a manageable size for emailing. But I will try. I have been meaning to write a
test app just to make sure the business object works as it should anyway. It
will take some time though, so don’t be surprised if I don’t get
back to you until tomorrow.
Thanks
Ute
From: RockfordLhotka
[mailto:cslanet@lhotka.net]
Sent: Thursday, June 26, 2008
10:39 AM
To: Willmore, Ute
Subject: Re: [CSLA .NET] RE:
OnUpdateObject EventHandler not called
Maybe you
can't get to CanUpdate - I've never really tried. It isn't intended for use by
a page developer, just by data binding.
But if
you put a breakpoint there and it didn't get hit, that seems to imply that data
binding never even tries to do the update - it never checks to even see if it
is possible, so it must not have gotten that far...
Can you
create a small test app that replicates the problem?
Sorry, didn’t necessarily mean to imply something you
could email – I am so buried I can’t research it.
But my approach with all complex issues like this is to try and
start with a new web project, add an object and a grid and see if I can
replicate the problem. Often this is quite revealing :)
Rocky
From: Willmore, Ute
[mailto:cslanet@lhotka.net]
Sent: Thursday, June 26, 2008 11:47 AM
To: rocky@lhotka.net
Subject: RE: [CSLA .NET] RE: OnUpdateObject EventHandler not called
I am not sure if I can reduce the code to a manageable size for
emailing. But I will try. I have been meaning to write a test app just to make
sure the business object works as it should anyway. It will take some time
though, so don’t be surprised if I don’t get back to you until tomorrow.
Thanks
Ute
From: RockfordLhotka
[mailto:cslanet@lhotka.net]
Sent: Thursday, June 26, 2008 10:39 AM
To: Willmore, Ute
Subject: Re: [CSLA .NET] RE: OnUpdateObject EventHandler not called
Maybe you can't get to CanUpdate - I've never really tried. It isn't
intended for use by a page developer, just by data binding.
But if you put a breakpoint there and it didn't get hit, that seems to imply
that data binding never even tries to do the update - it never checks to even
see if it is possible, so it must not have gotten that far...
Can you create a small test app that replicates the problem?
I understand and I will still try to
create a small project to see if the object can actually update. I should have
done that several days ago.
Thanks
Ute
From: Rockford Lhotka
[mailto:cslanet@lhotka.net]
Sent: Thursday, June 26, 2008
10:54 AM
To: Willmore, Ute
Subject: RE: [CSLA .NET] RE:
OnUpdateObject EventHandler not called
Sorry, didn’t necessarily mean to imply something you could email
– I am so buried I can’t research it.
But my approach with all complex issues like this is to try and start
with a new web project, add an object and a grid and see if I can replicate the
problem. Often this is quite revealing :)
Rocky
From: Willmore, Ute
[mailto:cslanet@lhotka.net]
Sent: Thursday, June 26, 2008
11:47 AM
To: rocky@lhotka.net
Subject: RE: [CSLA .NET] RE:
OnUpdateObject EventHandler not called
I am not sure if I can reduce the code to a manageable size for
emailing. But I will try. I have been meaning to write a test app just to make
sure the business object works as it should anyway. It will take some time
though, so don’t be surprised if I don’t get back to you until
tomorrow.
Thanks
Ute
From:
RockfordLhotka [mailto:cslanet@lhotka.net]
Sent: Thursday, June 26, 2008
10:39 AM
To: Willmore, Ute
Subject: Re: [CSLA .NET] RE:
OnUpdateObject EventHandler not called
Maybe you
can't get to CanUpdate - I've never really tried. It isn't intended for use by
a page developer, just by data binding.
But if
you put a breakpoint there and it didn't get hit, that seems to imply that data
binding never even tries to do the update - it never checks to even see if it
is possible, so it must not have gotten that far...
Can you
create a small test app that replicates the problem?
Rocky,
I finally found the problem with that
update event in my project this past Wednesday and I have been meaning to post
and tell you about it, because I think it may impact others as well.
It turns out that the problem was not in
my code for the page or the csla objects after all. The problem was in the
master page. We use the same base master page in all our applications, so we
maintain the same look and feel in all our web applications. The master page
was originally written for a specific application and we had hoped we could use
that master page as a global master page, so that all applications would look
at the same file. That turned out to be impossible and we ended up copying the
master page to each application directory. As a result of this original plan there
is some code behind the master page, but we just comment what we don’t need
or what interferes with the current application. So far that has not been a
problem, but it was a problem this time.
I commented one line of code after another
until I found the line that caused the problem for me. The offending line turned
out to look like this:
This.ID = “MP”
The code sets the ID of the current page
to “MP” (for Master Page). I am not sure why this is done, and the
programmer who wrote the master page does not recall the reason for it either,
but he thinks it had something to do with Ajax
and JavaScript.
Obviously we need to take a closer look at
our master page(s) and make sure we remove unused code and reduce the code
behind the master page to the minimum required. Since my application does not
use page IDs, my master page should not be resetting it.
We also need to do a better job at
commenting code so we don’t end up with code that no one remembers why it
was written. It is always possible to determine what the code does, but sometimes
it is hard to figure out why, and we need to document the why not the what.
Be that as it may though, I am curious to
find out why resetting the ID of the master page would mess up the event
handlers for the csla DataSource? I think I told you that my OnUpdateObject
handler was never called and that my OnSelectObject handler was always called,
even when I had clicked update and the Update handler should have been called.
I don’t understand why the update handler should be affected by the page
ID of the master page. Can you explain this to me? Did you expect this behavior
or did I stumble across something that is a problem for all users of the CSLA DataSource?
I hope you can take the time to answer my
questions and I want to thank you for helping me as much as you did while I was
trying to fix my code. I apologize for not responding to your last post, but I got
really into this problem I was dealing with and then had knee surgery and was
laid up for a couple of days. I am back at work now and I hope to hear from you
soon.
Thanks
URW
uwillmore:Can you explain to my why this is happening? Why is the Onselect Handler called when I clicked Update? It seems to me that the onselect handler not only wipes out my changes on the screen but it also clears the update event, though I don't understand why. Shouldn't the update handler becalled BEFORE the select handler is called? Do I need to test someplace to see if changes where made and prevent the OnSelect handler from updating the grid with data from the session? I don't see anything like that in the project tracker example code, but I am willing to try almost anything at this point.
Thank you for the complete description of the problem/solution - that's great!
I can't explain what is happening here. As I said earlier, I don't think it is an issue with CslaDataSource as much as with Web Forms data binding itself. Perhaps you've found a bug with data binding?
It certainly seems, from your description, that setting the id value somehow confused data binding so it was no longer delivering events from the UI controls to the data control. I think you clearly established that data binding was not invoking the CslaDataSource control, which is why I think you confused data binding itself, not the datasource control.
You may want to check in the ASP.NET forums on MSDN to see if this is just a known issue with Web Forms data binding?
So you think it is in the data binding not
in the CslaDataSource? Well, that is certainly what I am leaning towards
myself, and maybe I will try to recreate the problem one day using an object
data source to see if it shows up when I am not using a CslaDataSource.
I will check on this being a known issue
too, but until I established that the problem occurs when I am not using a CSLA
DataSource I doubt I will get much help from any of the Microsoft sponsored
forums. Still I may check with the ASP .NET forum when I have some spare time.
For now I have to skip any further investigation. This problem cost me a week
and I have to make up for lost time somehow.
Thanks again for the help
URW
Copyright (c) Marimer LLC