Need help with very simple implementation

Apr 26, 2011 at 3:22 AM

I am glad I stumbled upon this code, although my needs are rather simple this code has at least saved me several hours of work, I big thank you goes out to the developers.

I have portions of html page content saved in a database table, I would like to access my model from within this static content. RazorEngine is the perfect solution. Using FCKEditor I input some formatted HTML content and it gets saved into the table. Within this content I would like to have @Model.SomeData which references some properties of my model for that view.

I am struggling a bit with implementing this into an existing solution. I got RazorEngine up and running but not sure how to use it in my view.cshtml.

Here is my view before the RazorEngine implementation...

 

@model DiversionPrograms.Web.ViewModels.ContentSectionViewModel
@{
   
    Layout = null;
}
@foreach (var item in Model.GetSectionContent()) { if (!string.IsNullOrEmpty(item.Contents) && !string.IsNullOrWhiteSpace(item.Contents)) { Html.Raw(item.Contents); } }

 

 

What I would like to do is take the output from the Html.Raw(item.Contents) statement and pass it into the RazorEngine as the template parameter. Everything I have tried so far has produced an error.

What would the syntax look like?

Thanks

Coordinator
Apr 26, 2011 at 8:56 AM

I would introduce an extension method to the HtmlHelper class, something like:

 

public static string RenderTemplate(this HtmlHelper helper, string template)
{
  return helper.Raw(Razor.Parse(template));
}

public static string RenderTemplate<T>(this HtmlHelper helper, string template, T model)
{
  return helper.Raw(Razor.Parse(template, model));
}

 

That way, you should be able to call it as either:

 

@Html.RenderTemplate(item.Contents);

 

Or:

@Html.RenderTemplate(item.Contents, new { Name = "Matt" });
The latter would allow you to pass in a model to be merged with the template.

Apr 26, 2011 at 3:59 PM

Thanks for the help but there is a problem with writing this as an extension method. Under the this key word I see the error "Extension method can only be declared in non-generic, non-nested static classes".

Coordinator
Apr 27, 2011 at 9:28 AM
Edited Apr 27, 2011 at 9:28 AM

Hi,

You can only add static extension methods to a static class, so something like:

 

public static class HtmlHelperExtensions
{
    // Stuff here.
}
Apr 27, 2011 at 5:18 PM

Still no luck with this...

 

Here is my helper extension

public static class SectionContentParseExtensions
{
public static IHtmlString ParseSectionContent<T>(this HtmlHelper helper, string template, T model)
{
return helper.Raw(Razor.Parse(template, model));
}

}

in my view I call it like this

Snippet

@Html.ParseSectionContent(item.Contents, Model)


and I get the following error.

Unable to compile template. Check the Errors list for details.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: RazorEngine.Templating.TemplateCompilationException: Unable to compile template. Check the Errors list for details.

Source Error:

Line 12: 		public static IHtmlString ParseSectionContent<T>(this HtmlHelper helper, string template, T model)
Line 13: {
Line 14: return helper.Raw(Razor.Parse(template, model));
Line 15: }
Line 16:

Source File: D:\Visual Studio 2010\DiversionProgramsWeb\source\DiversionPrograms.Web\Helpers\SectionContentParseExtensions.cs    Line: 14

Stack Trace:

[TemplateCompilationException: Unable to compile template. Check the Errors list for details.]
RazorEngine.Compilation.DirectCompilerServiceBase.CompileType(TypeContext context) +119
RazorEngine.Templating.TemplateService.CreateTemplate(String template, Type modelType) +205
RazorEngine.Templating.TemplateService.GetTemplate(String template, Type modelType, String name) +83
RazorEngine.Templating.TemplateService.Parse(String template, T model, String name) +58
RazorEngine.Razor.Parse(String template, T model, String name) +66
DiversionPrograms.Web.Helpers.SectionContentParseExtensions.ParseSectionContent(HtmlHelper helper, String template, T model) in D:\Visual Studio 2010\DiversionProgramsWeb\source\DiversionPrograms.Web\Helpers\SectionContentParseExtensions.cs:14
ASP._Page_Views_Portal_ContentSection_cshtml.Execute() in d:\Visual Studio 2010\DiversionProgramsWeb\source\DiversionPrograms.Web\Views\Portal\ContentSection.cshtml:23
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +207
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
System.Web.WebPages.StartPage.RunPage() +19
System.Web.WebPages.StartPage.ExecutePageHierarchy() +65
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +76
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +303
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.Mvc.<>c__DisplayClassa.<EndProcessRequest>b__9() +23
System.Web.Mvc.<>c__DisplayClass4.<Wrap>b__3() +12
System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Func`1 func) +38
System.Web.Mvc.ServerExecuteHttpHandlerWrapper.Wrap(Action action) +65
System.Web.Mvc.ServerExecuteHttpHandlerAsyncWrapper.EndProcessRequest(IAsyncResult result) +71
System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +1045

[HttpException (0x80004005): Error executing child request for handler 'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'.]
System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride) +3014151
System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm, Boolean setPreviousPage) +77
System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +28
System.Web.HttpServerUtilityWrapper.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm) +22
System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues, TextWriter textWriter) +481
System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, RouteValueDictionary routeValues) +88
System.Web.Mvc.Html.ChildActionExtensions.Action(HtmlHelper htmlHelper, String actionName, String controllerName, Object routeValues) +46
ASP._Page_Views_Portal_Main_cshtml.Execute() in d:\Visual Studio 2010\DiversionProgramsWeb\source\DiversionPrograms.Web\Views\Portal\Main.cshtml:31
System.Web.WebPages.WebPageBase.ExecutePageHierarchy() +207
System.Web.Mvc.WebViewPage.ExecutePageHierarchy() +81
System.Web.WebPages.StartPage.RunPage() +19
System.Web.WebPages.StartPage.ExecutePageHierarchy() +65
System.Web.WebPages.WebPageBase.ExecutePageHierarchy(WebPageContext pageContext, TextWriter writer, WebPageRenderingBase startPage) +76
System.Web.Mvc.RazorView.RenderView(ViewContext viewContext, TextWriter writer, Object instance) +220
System.Web.Mvc.BuildManagerCompiledView.Render(ViewContext viewContext, TextWriter writer) +115
System.Web.Mvc.ViewResultBase.ExecuteResult(ControllerContext context) +303
System.Web.Mvc.ControllerActionInvoker.InvokeActionResult(ControllerContext controllerContext, ActionResult actionResult) +13
System.Web.Mvc.<>c__DisplayClass1c.<InvokeActionResultWithFilters>b__19() +23
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilter(IResultFilter filter, ResultExecutingContext preContext, Func`1 continuation) +260
System.Web.Mvc.<>c__DisplayClass1e.<InvokeActionResultWithFilters>b__1b() +19
System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(ControllerContext controllerContext, IList`1 filters, ActionResult actionResult) +177
System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName) +343
System.Web.Mvc.Controller.ExecuteCore() +116
System.Web.Mvc.ControllerBase.Execute(RequestContext requestContext) +97
System.Web.Mvc.ControllerBase.System.Web.Mvc.IController.Execute(RequestContext requestContext) +10
System.Web.Mvc.<>c__DisplayClassb.<BeginProcessRequest>b__5() +37
System.Web.Mvc.Async.<>c__DisplayClass1.<MakeVoidDelegate>b__0() +21
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +12
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +62
System.Web.Mvc.<>c__DisplayClasse.<EndProcessRequest>b__d() +50
System.Web.Mvc.SecurityUtil.<GetCallInAppTrustThunk>b__0(Action f) +7
System.Web.Mvc.SecurityUtil.ProcessInApplicationTrust(Action action) +22
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +60
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +8862381
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +184


Coordinator
Apr 27, 2011 at 6:57 PM

Well, that is now a different issue. The issue you are now having is that RazorEngine was unable to compile the template, so you've already got the extension method working. Now you need to figure out why the template can't compile. Put an example template here and also, what Model instance are you passing into the template?

Apr 27, 2011 at 9:08 PM

Ok I figured it out. I was not referencing my model correctly..

I was using

@Model.Case.CaseNo

rather than

@Model.CurrentUser.Case.CaseNo

I guess it would make more sense if the razorengine would produce an error message that is more intuitive in this case rather than just "Unable to parse template".
a null reference exception would have saved me a lot of time on this one.

Thank you for your help, looks like my implementation was successful!
Coordinator
Apr 28, 2011 at 4:51 PM

jbeckton, viewing the list of errors contained in the exception will usually point you to where the error lies