Rendering ASP.NET MVC Viewer by email

Last couple of days I had a bit of a trouble. I was working for a client that wanted to automatically notify his deliveries to the company that was doing the delivery. The task was just another branch of a bigger project.
I had managed to keep the project relatively simple in my view, and I did not want to start generating PDF's and then attaching to an email. All this automatically, of course.
The client is developing all the new software in .NET so the language wasn´t a choice. I was using the MVC framework and I had already a view that was rendering exactly what they wanted to be emailed. So I thought to myself "If I could just send the rendered view...".
I did a little bit of searching on the Web and found this on StackOverflow. Using one of the answers to the question I got this code working:

 Dim httpStream = New IO.MemoryStream()
Dim httpWriter = New IO.StreamWriter(httpStream, Encoding.Unicode)
Dim vp = New ViewPage()

Dim response = System.Web.HttpContext.Current.Response


Dim controlContext = New ControllerContext() With {.HttpContext = New HttpContextWrapper(New HttpContext(System.Web.HttpContext.Current.Request, response))}
vp.ViewContext = New ViewContext(controlContext, New WebFormView("~/Views/PathToView", ""), Me.ViewData, New TempDataDictionary())

'HACK: Inject custom TextWriter into the http response, then render, then put the response in it's original state and return
Dim httpWriterField = response.GetType().GetField("_httpWriter", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
Dim privateHttpWriter = httpWriterField.GetValue(response)
httpWriterField.SetValue(response, Nothing)

Dim writerField = response.GetType().GetField("_writer", Reflection.BindingFlags.NonPublic Or Reflection.BindingFlags.Instance)
writerField.SetValue(response, httpWriter)

vp.ViewContext.View.Render(vp.ViewContext, Nothing)

httpWriterField.SetValue(response, privateHttpWriter)
writerField.SetValue(response, privateHttpWriter)

httpWriter.Flush()
Dim output = Encoding.Unicode.GetString(httpStream.ToArray())
httpWriter.Close()
httpStream.Close()

//Send the output on an email


I don´t like the way this is done. You´ve got to go crazy to simply get some raw HTML as string. I'm sure there are better ways to do this. Anyone welcome to post suggestions.

As always there are advantages and disadvantages of having this complex rendering system. One of the disadvantages we have just seen. The code above using mochiweb in Erlang, would have been much easier because you have full control over how HTML is generated.

Comments

Popular posts from this blog

A case against bloom filters in bitcoin

To pray or not to pray