Using partials in Web Forms
Partial is a MonoRail term to a piece of UI that you extract outside, so you can call it again, often with Ajax. This is something that is harder to do in WebForms. Yesterday I found an elegant solution to the problem.
ASPX code:
<div id="UserDetailsDiv"> <ayende:UserDetails runt="server" ID="TheUserDetails"/> </div>
User Control:
<div> Name: <asp:label ID="Name" runat="server"/> <br/> Email: <asp:label ID="Email" runat="server"/> </div>
Client Side Code:
function changeUser(newUserId, div) { var srv = new MyApp.Services.UserDetails(); srv.GetUserDetailsView(newUserId, onSucccessGetUserDetailsView, null, div); } function onSucccessGetUserDetailsView(response, userContext) { var div = $(userContext); div.innerHTML = response; new Effect.Highlight(div); }
Web Service Code:
[WebMethod(EnableSession = true)] public string GetUserDetailsView(int userId) { User user = Controller.GetUser(userId); //there may be a better way to do this, I haven't bothered looking UserDetails userDetails = (UserDetails)new Page().LoadControl("~/Users/UserControls/UserDetails.ascx"); userDetails.User = user; userDetails.DataBind(); using(StringWriter sw = new StringWriter()) using(HtmlTextWriter ht = new HtmlTextWriter(sw)) { userDetails.RenderControl(ht); return sw.GetStringBuilder().ToSTring(); } }
Comments
I did something similar some year ago when I needed to update a search list through an Ajax callback. It works but I am not sure I would call elegant, at least not compared to the MonoRail solution =)
Torkel,
It is elegant compared to the alternative.
I guess you are right, and it is nice to be able to reuse the user control for the Ajax scenario.
Maybe this could make it even nicer:
return RenderUserControlForAjax<UserDetails>("~/Users/UserControls/UserDetails.ascx",
Hey,
That is the kind of code that I would write!
man that's sweet and simple
It's always good to search the Net before implementing something. Chances are someone did it already:
http://weblogs.asp.net/scottgu/archive/2006/10/22/Tip_2F00_Trick_3A00_-Cool-UI-Templating-Technique-to-use-with-ASP.NET-AJAX-for-non_2D00_UpdatePanel-scenarios.aspx
I suppose we should not consider you guilty of NIH syndrome, as this kind of code is quick to write :)
I had some something similar to this in a previous project, however the issue often came up when the session was timed out but you could still trigger the javascript actions on the page without checking for an active session. This would often result in unpredictable ajax behaviors and messy session checking code in nearly every ajax call prior to the render.
How have others dealt with that issue?
By making the session state implicit to the request.
If the session doesn't exist, it means that you can't do anything.
A few things dear friend,
notice that the Render method of the control does not call the entire ProcessRequest lifecycle, hence this is nice for user controls that only render GUI, but if you'd like to use the OnInit, OnPreRender etc. for DataBinding and so forth, it could get painfull.
If you Pre Compile the Web App the UserControls are not longer at the path that you have assumed to would be... take that under advisment.
WRITE IN MONORAIL, WHY THE BLOODY HELL ARE YOU DOING THIS TO YOURSELF?!?
1/ Not an issue, I have learned to do the simplest thing possible with WebForms, other wise I regret it.
2/ Not an issue either, that is not planned.
3/ There is this pesky client that thinks that just because he is paying, he get to decide what will happen.
It is a bit of a nasty hack really ... used it a few times many years ago (or very similar) for rendering order form confirmations to email bodies.
For really simple things it works. For complex stuff it is just painful.
Comment preview