Last Updated: November 28, 2020
·
1.473K
· tryingtoimprove

Using Razor in a Custom DynamicWeb Module (PROOF OF CONCEPT)

Using Razor in a Custom DynamicWeb Module (PROOF OF CONCEPT)

I am sorry for my bad english.. :-(

I have started working with DynamicWeb (cms). With DynamicWeb you have the ability
to develop custom modules for you pages. These custom modules can contain custom C# code, that you can use to develop more custom stuff.

I want to tell you how you can use razor in you modules..
Normally you would write code as this:

StringBuilder strBuiler = new StringBuilder();
strBuiler.Append("<h1>" + model.Headline + "</h1>");
strBuiler.Append("<hr />");
strBuiler.Append("<ul>");
foreach (var name in model.Names)
{
    strBuiler.Append("<li>" + name + "</li>");
}
strBuiler.Append("</ul>");

That code is not pretty or easy to bugfix. If you have worked with ASP.net MVC and Razor, then the result will look familiar:

@using CustomModules.HelloWorld //normal using
@inherits RazorEngine.Templating.TemplateBase<NameMViewodel> //Setting the Model

<h1>@Model.Headline</h1>
<hr />
<ul>
    @foreach (var name in Model.Names)
    {
        <li>@name</li>
    }
</ul>

Setting up

To do this I need 2 dependencies

When I have added these 2 dependencies to my project I am ready to create some sort of loader.

Visual Studio

Visual Studio is not very happy to have razor-files when you not develop a MVC project. You can get around this by adding this code to your web.config file:

<system.web>
  <compilation>
    <buildProviders>
      <add extension=".cshtml" type="RazorEngine.Web.CSharp.CSharpRazorBuildProvider, RazorEngine.Web" />
      <add extension=".vbhtml" type="RazorEngine.Web.VisualBasic.VBRazorBuildProvider, RazorEngine.Web" />
    </buildProviders>
  </compilation>
</system.web>

If you run on Medium Trust then take a look here: http://razorengine.codeplex.com/wikipage?title=Configuring%20RazorEngine%20for%20ASP.NET%20Medium%20Trust

Razor Loader

I have built a small class that can read a razor-file and return the generated HTML:

public class RazorLoader
{
    public string GenerateHtml<T>(string razorViewPath, T model)
    {
        string result;

        using (Stream stream = new FileStream(
            HttpContext.Current.Server.MapPath(razorViewPath),
            FileMode.Open,
            FileAccess.Read))
        {
            using (StreamReader reader = new StreamReader(stream))
            {
                result = RazorEngine.Razor.Parse(reader.ReadToEnd(), model);
            }
        }

        return result;
    }
}

Using it!

Now I am ready to use the razor loader in a ContentModule:

public class NameMViewodel
{
    public string Headline { get; set; }
    public List<string> Names { get; set; }
}

[AddInName("RazorTester")]
public class RazorTester : ContentModule
{
    public override string GetContent()
    {
        var model = new NameMViewodel
        {
            Headline = Properties["Headline"].ToString(),
            Names = new List<String>() { "Oliver", "Kim", "Lars", "Micheal" }
        };

        return new RazorLoader().GenerateHtml("~/CustomModules/RazorTester/test.cshtml", model); ;
    }
}

Conclusion

Do it! It seems to work.. ;-) There are some missing features in RazorEngine, but basic works.

Update 1

The RazorEngine can be very slow if you not specify a cacheName when you parse the Razor code..

Razor.Parse(razorTemplate, viewModel, cacheName);

2 Responses
Add your response

Have you tried using this in production? I mean on live websites?
/Sten

over 1 year ago ·

It partly working !
If I know all my model properties its no problem, but I want to be able to print out all my model tags using @TemplateTags() (of Dynamicweb) in my cshtml template.

I cant convert RazorEngine.Templating.TemplateBase<Dynamicweb.Rendering.Template> to Dynamicweb.Rendering.RazorTemplateBase<Dynamicweb.Rendering.RazorTemplateModel<Dynamicweb.Rendering.Template>>

over 1 year ago ·