Search code examples
c#asp.net-mvcrazorlambdarazorengine

Antaris RazorEngine - Helper Lambda Expressions


Disclaimer

If you notice any false assumptions in anything below, please let me know. I've put a decent amount of work into this, but if there's a better way I am happy to throw what I have out.


Short Version

I need to replicate the functionality of MVC's @Html.DisplayFor() function without access to the Controller Context.


Background

I'm trying to generate PDF documents from Razor (.cshtml) files. I was previously using Rotativa (based on wkhtml), which seemed to work fairly well. However, I'm going to need to generate hundreds of documents at times, and I would like to do this asynchronously to save time. Unfortunately, it seems that anything asynchronous cannot access the Controller context, which is required by Rotativa. Further, research indicates that wkhtml in general can't be run asynchronously.


Current Attempted Solution

So, now I'm trying to use Antaris RazorEngine to render the Razor views to HTML strings without using the controller context. Then, I will feed that HTML into iTextSharp to make the PDF. I believe this should be able to run asynchronously (if anyone knows something to the contrary, please correct me).


The Problem with the Solution

Our Razor views heavily rely on the HtmlHelper object (which requires access to the Controller Context) to do things like @Html.LabelFor() or @Html.DisplayFor(). I believe I have been able to replicate the LabelFor functionality as a stand-alone helper method. Unfortunately, the DisplayFor method is proving more challenging. With LabelFor I just had to get information about the attributes of the object passed in via lambda expression. In contrast, DisplayFor needs to get the value of the object passed in via lambda expression.


What I've Tried

  • I've reviewed dozens of posts (example) about getting the value that all require access to the htmlHelper object, and therefore the ControllerContext, which won't work.
  • I've found a few posts (example) that seem quite similar to what I'm trying to accomplish, but they seem to require access to the Model object, which I'm not sure I can get. All I really have available to me is the data that is in the lambda expression.

I apologize for the wall of text; I tried to break it up as best as I could. Thanks in advance for any suggestions!


Solution

  • Of course after typing all of that up, I discovered the simple solution: pass the model from the view as a parameter to the helper function.