Search code examples
asp.net-mvchtml-emailhtml-helper

Where should I put shared HTML generation code in an ASP.NET MVC project?


I have an ASP.NET MVC solution, and I have a large number of HtmlHelper classes inside the ASP.NET MVC project that take data and generate various snippets of html to display on various pages.

I now have to run a bunch of scheduled jobs and many of those jobs generate emails. I moved all of these jobs into a separate project in the solution (called AdminJob.csproj), but I now find that I have to generate a number of email with very similar HTML as I have in my view pages. I am trying to keep the admin jobs from having a dependency on the ASP.NET MVC project (as I would like to run the adminjob project as a command line if required), and I also want to avoid having my ASP.NET MVC project having a dependency on the AdminJob project (as that just seems odd).

Any suggestions on how I can avoid duplicating the same HTML rendering code in both my ASP.NET MVC project and my AdminJob project?

The only thing I can think about is creating another project in the solution called "ViewHelpers" or something like that and move all of my HTMLHelpers into that project so it can be referenced by both my MVC project and the AdminJob project. It seems a bit overkill to have a separate project just for this code, but I can't think of another solution that doesn't create duplication.

Any other suggestions for a better way to do this and avoid any duplication?


Solution

  • The way I look at this is that the email is a view type.There are several view types in my web apps (html, email, pdf, rss etc). There are several implementations of this pattern: ActionMailer in ruby on rails or its port to asp.net: MvcMailer.

    This way you can take full advantage of the Razor engine in both your web application and your emails in order to reduce duplication.

    You can host your views in another project and inform your ViewEngine about where to look for the views (see Views in separate assemblies in ASP.NET MVC). I find this to be overkill.

    Another way - the one I use - is to have the email templates in the same project with other views.

    If you want to render the views outside of a web application you can compile the razor templates in a console app using one of these: