Tuesday, January 20, 2009

RenderPartial to String in ASP.NET MVC Beta

This has been an interesting journal working with ASP.NET MVC. I started working with the MVC Framework back in April 2008 while it was Preview 3. I was on a contract in Los Angeles with the Department of Public Health and was very excited. This was my first opportunity to work on the new release of Visual Studio 2008 which had not officially been released to the public, but because this was a government institution, Microsoft was hooking the government up first. The director was an older gentleman with lots of experience in C & C++ programming. He loved what C# brought to programming and expressed his love for the .NET Framework. He brought me on board as a Principal .NET Developer to help him get the development department in shape. My experience is just what he needed to get the development department more standardized. The ASP.NET MVC Framework was exactly what he thought would strengthen the process and make applications more object oriented.

I was quite familiar with microsoft's windows MVC, but wasn't to keen on the ASP.NET MVC model, so I had a learning curve. I have always been blessed with the ability to learn new technologies pretty easily, so I wasn't to concerned. I was put in charge of 3 Senior .NET Developers what were in the same boat as myself, so it was important for me to learn fast so that I could be of assistance to my developers. I became quite facinated with the ASP.NET MVC Framework and loved the methodology by which it allowed you to seperate the Model, View and Controller layers. This is exactly what I had been wishing for. I spent years using ASP.NET and never liked the page lifecycle. This was primarily because I started using AJAX with ASP.NET a few years back and hated how I didn't have much control of page processing unless I used a HTTP Handler. As I got more and more familiar with the ASP.NET MVC Framework, I loved how much control it gave you. My Director wanted to use a client side Javascript library called YUI to build more intrigueing interfaces, so I had to dig in and find out how to use this library with the ASP.NET MVC Framework.

I must admit, this was a difficult process because, there wasn't much documentation on how to do this. Plus, the YUI was a little unstable because it was Beta and their documentation wasn't quite up to what I thought it should be. At the time, I was very familiar with a different Javascript library called ExtJs that to me was more superior than the YUI, so I did my best to convince the Director to us ExtJs instead, but he shot me down stating that the .NET Architect thought the YUI would be perfect for the project. So, I didn't want to cause and ripples, so I proceeded to dig into the YUI documentation to get a better understanding. Man, I tell you, this experience with the YUI was making me love the ExtJs library all that much better.

Billy McCafferty, the .NET Architect was very bright and had extensive knowledge with NHibernate and Spring.NET. He turned out to be the owner of Codai, LLC and orginator of S#arp Architecture - http://devlicio.us/blogs/billy_mccafferty/archive/2008/11/12/s-arp-architecture-0-9-released.aspx . I knew nothing about any of this and was eager to learn. The only problem was Billy nor I had time for one on one training like we wanted. I did get an opportunity to learn a little about NHibernate, but I was still confused about some aspects of what I had learned and no one was about to assist me in getting a better understanding.

The project proceeded about 2 months and the results were not looking too good. The YUI library was a beast and none of the developers were enjoying the journey. We ended up going past our release date and had an application that was quite unstable. In my mind, I was confident that if we had chosen ExtJs over YUI, we would have been a whole lot further a long and this wasn't because YUI sucked but because my experience level with ExtJs was much greater. I would have been able to lead my developers a whole lot better that how I was, which was, "the blind leading the blind".

I ended up leaving this organization back in July 2008 because of my Health issues. I moved back to Colorado Springs, CO with my wife and kids and got a job at Current USA Inc. as a Web Developer. Life is much different now, but I do miss the Department of Public Health sometimes. I am now working on a website redesign of http://www.currentgiftcards.com/ that is running on the ASP.NET MVC Framework. I am working with some pretty sharp developers who are eager to improve on the current website. I am bringing my experience with AJAX and Javascript to the table and hoping to improve the user experience of the website.

My of my tasks is to create a modular Javascript Framework that allows us to reuse a lot of the widgets we are building for the website. The Javscript Framework choosen for this project was the YUI and of course I was hating the thought of having to go through this all again. But, this time, I tried to have a much different attitude so that I could atleast give this another chance. I started to dig into the documentation again for information on some of the widgets we were going to implement. I started to find out that the documentation looked like it had been improved and a percentage of the library wasn't in Beta stage anymore. That kind of made me excited to finally get something with a little more stability. So, I charged on in and started implementing some of the widgets. The API's aren't as robust as ExtJs, but they are very usable, so I kept a positive attitude and built my first Carousel and Dialog and was pretty happy with the results.

Using the ASP.NET MVC Framework and YUI seems to be a perfect match. I created a Javascript Module to handle AJAX calls back to the server and the functionality was great and performed very well. One of the things that I wanted to do with the ASP.NET MVC Framework was render a UserControl as a string and emit it to the client for population into the DOM. Well, unfortunately, there wasn't a built in easy way to do this. After reading some blogs and trying different solutions that failed, I was at a loss. Then it hit me, why not use what I used to use in ASP.NET to render HTML, the renderControl method of the control object. So, I implemented a static class to perform the conversion process -

public static string RenderUserControl(string controlName, System.Web.Mvc.ControllerContext controllerContext) { System.Web.Mvc.ViewPage vp = new System.Web.Mvc.ViewPage(); vp.ViewContext = new System.Web.Mvc.ViewContext(controllerContext, new System.Web.Mvc.WebFormView("."), null, null); //vp.ViewContext = new System.Web.Mvc.ViewContext(controllerContext, new System.Web.Mvc.WebFormView("/Views/Samples/View.aspx", "/Views/Shared/Site.Master"), null, null); Control control = vp.LoadControl(controlName); vp.Controls.Add(control); StringBuilder sb = new StringBuilder(); using (StringWriter sw = new StringWriter(sb)) { using (HtmlTextWriter text = new HtmlTextWriter(sw)) { vp.RenderControl(text); } } return sb.ToString(); }

What this did for me was allow me to pass the usercontrol name to this method and get a string returned to emit to the client AJAX call handler. This was a thing of beauty and a whole lot better solution than what I had been finding on google. Now, we can design our interfaces the way we want in a usercontrol and spit out the HTML to be placed in the user interface using AJAX.

Well, off to learn some more. Take Care and Have a Great Day.

2 comments:

Dan said...

Hi there!

This is a very tight solution, but alas, I can't see where you can add models and ViewData.

Any ideas?

walkins5 said...

Hello Dan,

Sorry for the delay in getting back to you. I have not been checking this blog as I used to. I have been so deep into my projects that I haven't been finding time to blog anymore. Sorry. As for your answer, in this solution, you will have to use the Session to pass your data unfortunately. The viewdata didn't work in this situation, but I was able to make due with using Session. Hope that helps. Take Care and Have a Great Day.

Charles