Exploring the depths and potentials of ASP.NET RSS 2.0 or Subscribe to .BenRush by Email
 Wednesday, May 10, 2006

This is an interesting exception that you might get when dealing with Ajax; more specifically, when trying to assign an EventName to a trigger. The situation might look something like this in your .aspx code:

                                <atlas:UpdatePanel runat="Server" ID="MainBody">
                                    <Triggers>
                                        <atlas:ControlEventTrigger ControlID="LinkButton1" EventName="OnClick" />
                                    </Triggers>
                                    <ContentTemplate>
                                        <%=System.DateTime.Now().ToString()%>
                                    </ContentTemplate>
                                </atlas:UpdatePanel>

What this block of xml script is telling the Atlas server framework to do is find the server control "LinkButton1" in the control tree and handle it's event "OnClick". It does this by telling the <ScriptManager> to first swallow any submit events for this client control (so that the form doesn't do a full postback) and then send back an asynchronous form post instead (basically intercepting the full postback and turning it into a partial postback). The stack trace for the exception is raised from within the Initialize() method of the Microsoft.Web.Atlas.ControlEventTrigger type:

protected internal override void Initialize(Control ownerControl)
{
   ....
   EventInfo info1 = null;
   string text1 = this.EventName;
   if (text1.Length != 0)
   {
      info1 = control1.GetType().GetEvent(text1);
   }
   if (info1 == null)
   {
      throw new InvalidOperationException("The EventName must be set to a valid event name on the associated control.");
   }
   ...
}

Note that it does a control1.GetType().GetEvent() on the data type of the control you're hooking the event on. So...go back and look at your control. As the exception suggests, you're hooking an event on the control that doesn't exist. The confusing part, however, is that you may think that it's hooking CLIENT events, but it's not...the ScriptManager is snagging the client events that cause a postback on this client control, doing a parital postback for it, and then updating the region of the UpdatePanel based on the response from that partial postback. The UpdatePanel, itself, isn't actually doing the postback (in other words, it's the ScriptManager control doing the partial postback, not the UpdatePanel).

....in the case of the XML Script above, to fix it you simply replace "OnClick" (the clientside eventname) with "Click" (the server side eventname).


kick it on DotNetKicks.com
Wednesday, May 10, 2006 2:46:12 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Computing

....then I'd recommend downloading the Windows Live Messenger (basically, the next generation of MSN messenger) from here. I'm currently in the process of the download right now, so I can't give any critical feedback at the moment.


kick it on DotNetKicks.com
Wednesday, May 10, 2006 1:26:10 AM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Computing

....I created this outline of how runtime types are loaded by the CLR. I just re-discovered this outline and thought I would post it for everyone's bedtime reading enjoyment ;)

 


kick it on DotNetKicks.com
Wednesday, May 10, 2006 1:23:42 AM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Computing

Today I was checking the referrer URLs in my blogs statistics and one of them came out to be this address: http://alternativeviagra.drugsmedic.com/.

After visiting the site, I still am confused as hell as to how THAT referred someone to MY blog.


kick it on DotNetKicks.com
Tuesday, May 09, 2006 11:00:02 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Ranting
 Tuesday, May 09, 2006

....come and get em.


kick it on DotNetKicks.com
Tuesday, May 09, 2006 3:26:52 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Computing

....I would treat this post by Scott Gutherie as the landing page for any questions you may have regarding Roles, Membership and Profile providers.


kick it on DotNetKicks.com
Tuesday, May 09, 2006 3:24:09 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Computing

....point yourself here. Notice the smooth, clean user experience and the lack of browser postbacks when using them - this is what Atlas is all about.


kick it on DotNetKicks.com
Tuesday, May 09, 2006 1:38:47 PM (Central Standard Time, UTC-06:00)  #    Comments [0] - Trackback
Computing

Atlas developers - especially Atlas developers working with classic ASP.Net applications - are going to fall in love with <UpdatePanel> controls because they make migrating traditional ASP.Net 1.x/2.0 applications to Atlas a breeze (er, for the most part). You will run into issues, at times, when dealing with update panels because, even though they are pretty solid in implementation and require (sometimes) no changes in code on the server - they still can break existing code. Understanding the internals of them is always a benefit.

The syntax for an update panel is simple, and looks like this:

<atlas:UpdatePanel runat="server" ID="UpdatePanel5">
   ... controls that will now be AJAX'd ...

</atlas:UpdatePanel>

Pretty harmless looking actually. What you do is simply surround surround your classic ASP.Net controls with these tags and *voila*, you suddenly enabled them all for partial postbacks. If you have a button and a textbox inside the UpdatePanel tags, and when you click the button the text box says hello, you can now do this without forcing the rest of the web page to render. There are several features to the UpdatePanel, and I'm not going to restate them , so if you're curious look here because the topic of this blog post is how the Atlas framework enables you to simply surround your original ASP.Net controls with a single tag and turn them into something which supports partial postbacks.

The slight of hand behind the whole process is the onsubmit handler in the form tag for every Atlas application:

<form name="form1" method="post" action="UpdatePanel1_cs.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="form1">

The method is large - too large to paste in this post in its entirety - but its function is simple: to detect if partial postbacks are enabled for the page, and if so, swallow any submit event that originates within an UpdatePanel (which are typically rendered as <span> or <div> tags in the HTML) and, in its stead, send an asynchronous form post back to the server. It registers a handler method for dealing with the response from the server and parses data out and updates the content using standard DHTML tricks. The main lines of code to take note of within the Submit method follows:

var request = new Sys.Net.WebRequest();
request.set_url(form.action);
request.get_headers()['delta'] = 'true';
request.get_headers()['Cache-Control'] = 'no-cache';
request.set_timeoutInterval(90000);
request.set_priority(Sys.Net.WebRequestPriority.High);
request.completed.add(Function.createDelegate(this, this._onFormSubmitCompleted));
request.timeout.add(Function.createDelegate(this, this._onFormSubmitTimeout));
request.set_body(formBody.toString());

_request = request;
this.raisePropertyChanged('inPostBack');
request.invoke();

One main point of interst is the creation and setting of the 'delta' header variable. For partial postbacks, this particular header is always there for it is this that clues the server-side framework into the fact that a partial postback is occuring, and to format the response stream in such a manner that the client can easily and effeciently parse out the change or "delta" in the browser content. A summary of fiddler response for a partial postback follows:

HTTP/1.1 200 OK
Cache-Control: no-cache
Date: Tue, 09 May 2006 03:56:25 GMT
Pragma: no-cache
Content-Type: text/xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Vary: Accept-Encoding

<delta>
..........
</delta>

Pay special attention to the fact that the response type is text/xml - this is because the response is, yes, XML. If you scan the method that deals with the server response, it is littered with dozens of XPath expressions that tear out of the response pertinent bits of information for DHTML-based updating of controls. For example:

..........
var
hiddenFields = delta.selectNodes('/delta/rendering//input[@type="hidden"]');
for (var j = 0; j < hiddenFields.length; j++) {
   var id = hiddenFields[j].attributes.getNamedItem('id').nodeValue;
   var value = hiddenFields[j].attributes.getNamedItem('value').nodeValue;

   var hiddenFieldElement = document.getElementById(id);
   if (!hiddenFieldElement) {
      hiddenFieldElement = document.createElement('input');
      hiddenFieldElement.id = id;
      hiddenFieldElement.name = id;
      hiddenFieldElement.type = 'hidden';
      _form.appendChild(hiddenFieldElement);
   }
   hiddenFieldElement.value = value;
}
..........

Now the server-side components that come into play here reside within the server-side code for the ScriptManager control. Particularly, two methods are of interest: first, the one that identifies we're dealing with partial postbacks and the one that generates the response stream for the client. The following bit of code within the ScriptManager hooks the .Render method (in the same way that the .Render method is hooked when inline [WebMethod] calls are made) to override the page's normal output and send custom output:

if (this._inPartialRenderingMode)
{
   RenderMethod method1 = new RenderMethod(this.RenderPageCallback);
   this._page.SetRenderMethodDelegate(method1);
}

When the page housing the ScriptManager control is asked to render, the following method is called instead:

private void RenderPageCallback(HtmlTextWriter writer, Control pageControl)
{
   Page page1 = (Page) pageControl;
   HttpResponse response1 = page1.Response;
   response1.Cache.SetCacheability(HttpCacheability.NoCache);
   response1.ContentType = "text/xml";
   writer.Write("<delta>");
   ....
   writer.Write("</delta>");
}

...which builds the response the client framework expects (an XML document).
kick it on DotNetKicks.com
Monday, May 08, 2006 11:54:48 PM (Central Standard Time, UTC-06:00)  #    Comments [2] - Trackback
Computing

Computers Blogs - Blog Top Sites

Archive
<May 2006>
SunMonTueWedThuFriSat
30123456
78910111213
14151617181920
21222324252627
28293031123
45678910
Blogroll
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2009
Benjamin Rush
Sign In
Statistics
Total Posts: 444
This Year: 0
This Month: 0
This Week: 0
Comments: 128
Themes
Pick a theme:
All Content © 2009, Benjamin Rush
DasBlog theme 'Business' created by Christoph De Baene (delarou)