Jan 28
In-memory view rendering with Spark
icon1 Darrell Mozingo | icon2 ASP.NET MVC | icon4 January 28th, 2010| icon32 Comments »

We recently had a requirement to start printing some documents from our web application. These documents required some very precise positioning of a few elements that can’t be achieved with standard web browser printing capabilities. After weighing our options, we decided to go the generated PDF route. There’s quite a few HTML -> PDF generation options out there, but they almost all require you to either point them at an HTML document on disk or feed them a string of your HTML. Options, options, options. Yea, I think we’ll take the string route, thanks.

Turns out (surprise surprise!) that getting your rendered HTML from the Web Forms view engine that’s used by default in ASP.NET MVC isn’t so, um, easy. It likes its HttpContext with a side of HttpSession, and that’s just the appetizer. Kind of hard to get that to it in-memory without firing up a whole other server instance. Thankfully, it turns out our good friend Spark makes rendering a view to an HTML string in-memory incredibly easy.

How? Glad you asked:

public static string RenderViewToHtml<VIEW_MODEL>(string viewPathAndName, VIEW_MODEL viewModel) where VIEW_MODEL : class
{
	var templatesLocation = new FileSystemViewFolder(HttpContext.Current.Server.MapPath("~/Views"));
	var viewEngine = new SparkViewEngine(BuildSparkSettings()) { ViewFolder = templatesLocation };
	var descriptor = new SparkViewDescriptor().AddTemplate(viewPathAndName);
 
	var view = (SparkView<VIEW_MODEL>)viewEngine.CreateInstance(descriptor);
	view.ViewData = new ViewDataDictionary<VIEW_MODEL>(viewModel);
 
	string html;
 
	using (var writer = new StringWriter())
	{
		view.RenderView(writer);
		html = writer.ToString();
	}
 
	return html;
}
 
public static SparkSettings BuildSparkSettings()
{
	return new SparkSettings()
		.AddNamespace("System.Linq")
		.AddNamespace("System.Web.Mvc")
		.AddNamespace("Microsoft.Web.Mvc")
		.SetPageBaseType(typeof(SparkView))
		.SetDebug(false);
}

Simply pass in a path to your view (minus the /View part) along with a view model and you’ll get back a string full of rendered HTML goodness. The BuildSparkSettings() method can shared with the application startup code where you create and add Spark as an ASP.NET MVC view engine. Here’s a sample call:

It’s worth noting that Spark and WebForms views can happily live side-by-side in a single project, too. We use this for only a hand full of pages and the rest are still using the WebForms view engine. Plus, converting them to Spark was as simple as renaming the file and adding a view model declaration at the top of the page (along the lines of <viewdata model="OurNeatViewModel" />). Granted these pages aren’t really leveraging the power and beauty of Spark, but they still run and with virtually no modifications.

Will we be converting all of our views to Spark and using some of it’s neat-o features and conventions? Probably not any time soon. While lots of folks are apparently feeling lots of pain with Web Forms views, we’re not (well, other than this whole in-memory rendered affair anyway). So there really isn’t much gain for us from switching over. I also really don’t like the non-strongly-typedness of their views, which already bit me a few times just on the hand full of views we’re using it for. Perhaps that might get fixed or ReSharper will step up with support for it.

Spark does have a lot of neat features though. It’s ability to easily render a full view to an HTML string in-memory was just the first thing we needed from it. I’m sure there’ll be more in the future.

Jan 16
Downtime
icon1 Darrell Mozingo | icon2 Misc. | icon4 January 16th, 2010| icon3No Comments »

downtime

My home-ran Linux server crashed shortly after the first of the year. I’ve gotten really good up time with it since I started using it 6 years ago, with only a power supply dieing on me once, and other than that having gone years at a time without having to do a single thing – even rebooting. Well, I’m thinking the motherboard gave out this time, and I really don’t feel like messing with the server any more between software updates and hardware issues (plus it was hosted in my company’s data center, and with a few of the ideas I’m hoping to bring to fruition this year, I don’t want to overstay my welcome there!).

So I moved to an actual hosted solution with Site5. I never realized it’d be so hard to find a freakin’ provider! I understand it’s probably the nature of the beast, but it seems like there’s no single provider out there that damn near everyone just loves, even as you move up the price scale. For every story about someone being with a host for years without a single problem, there’s one where they guy’s site was down every other day and he lost half of his data in a crash. Eek! I’ve have heard good things about Site5’s Ruby on Rails hosting and their uptime in general, however, plus they provide SVN & Git on all their servers so I don’t have to worry about hosting that separately with GitHub or Unfuddle, so I took the plunge for a year to try them out. Pretty good so far, though there were a few hiccups such as having to move my DNS hosting to them and at least one server outage. Guess I’ll see how it goes.

Anyway, that’s why the site was done for two weeks or so. Hopefully it shant happen again any time soon.

Jan 3
2010 Goals
icon1 Darrell Mozingo | icon2 Goals | icon4 January 3rd, 2010| icon3No Comments »

Time to lay out some professional and coding related goals for 2010:

Books

  1. Code Complete – Steve McConnell
  2. Patterns of Enterprise Application Architecture – Martin Fowler
  3. Applying Domain-Driven Design and Patterns – Jimmy Nilsson
  4. Working Effectively With Legacy Code – Michael Feathers

Tools/Techniques/Processes @ Work

  • Move from SVN to Git (and learn more about Git in the process).
  • Move from CC.NET to Team City for our build server.
  • Build a more robust build script and management process – including production deployment and database migration scenarios.

Involvement

  • Develop an idea I was given for an open source project and get it live to see what happens.
  • At least 24 blog posts (I’m not going to say 2 per month as I’m getting married this summer and I’m certain I won’t be able to maintain a schedule around it).
  • At least 3 feature/patch submissions to open source projects.

Coding

  • Get a version 1 out there on at least 1 of the 3 product ideas I have floating around.
  • Keep working on a good working knowledge of Ruby & Ruby on Rails (and use it to build the product mentioned above).

Pretty similar to last years goals overall, actually. I’ll be updating my progress every 3 months instead of 2 this year though.

Set any goals yourself this year?

Jan 2
2009 Goals – Year End Update
icon1 Darrell Mozingo | icon2 Goals | icon4 January 2nd, 2010| icon31 Comment »

2009’s over. How did I do on my goals for last year? Let’s see (comments in italics after each goal):

Books

  1. Code Complete – Steve McConnell (yep, I’ve never actually read it)    No progress.
  2. Patterns of Enterprise Application Architecture – Martin Fowler    No progress.
  3. Domain Driven Design – Erick Evans    Done.
  4. Working Effectively With Legacy Code – Michael Feathers    No progress.

Tools/Techniques/Processes @ Work

  • NHibernate and all its trimmings (FluentNHibernate, LINQ to NHibernate, etc), which I’ll need on a project here real soon.  Done.
  • Actually move from CC.NET to Team City (last attempt didn’t go so well).  No progress.
  • Build a more robust build script and management process – including production deployment scenarios.   No progress.
  • Messaging framework, either MassTransit, NServiceBus, or Ayende’s new Rhino Service Bus if he’s able to release it in time for our current project.  Didn’t need it, so no progress.

Involvement

  • We have weekly meetings to catch everyone up on what we’re doing, but I want to present on an actual topic during at least 2 of these – and present in a way where the other development teams will see the use in picking up the presented tool/technique.    Meetings still halted – no progress.
  • Have at least one meeting of the CantonALT.NET group and see if it can ever get up on its feet.   No progress, and more than likely dead in the water 🙁
  • The two blog posts per month target John put out there seems doable, so I’ll borrow it 🙂    Spot on, but no posts during October or November. I’ll consider this goal missed, then.
  • At least 3 feature/patch submissions to open source projects.  Done.

Productivity

  • Trim RSS feed size by 1/3 (presently at 127, so trim it to at least 85) and cut time viewing it by half. I’ve gotten much better this past year at cutting through the useless stuff, but there’s still a lot there and it sucks up too much of my time.  Done.

So, overall I completed 4 of my 13 goals – 31%. Ouch. To be fair, 2 of the goals were out of my hands (didn’t need a messaging framework at work yet and didn’t want to think up some rinky-dink example project to try it on, and our weekly meetings were cancelled for me to present – though I could have found another venue to present). I was also pretty close on the blog posting goal, only missing a few because I ran short on ideas for a couple of months there.

Ah well, at least I gave them all a shot and completed at least one from each category. I also knocked off a lot of my personal goals for the year, so they sort of balanced out. I’ll post my code related goals for the upcoming year later this week.

How’d everyone else do? Have any new ones for this year?