RazorEngine - @Html.LabelFor OK, @Html.EditorFor "not implemented exception" on Execute()

1.1k views Asked by At

I am evaluating RazorEngine at the moment to see if it can be used in our project - we need to reorder the fields in a view dynamically, so I'm trying to send a string to RazorEngine to get the full HTML and show that to the user.

I have used RazorEngine with @Html.LabelFor() and it works fine. I used mao47's code on this SO post: https://stackoverflow.com/a/19434112/2878135 which is based on Abu Haider's code: http://www.haiders.net/post/HtmlTemplateBase.aspx

But this does not work for @Html.EditorFor() . I get a System.NotImplementedException thrown - method or operation is not implemented. This is from a new MVC4 project. No code changes have been made other than to implement the code from mao47.

I have the RazorEngine source code and the error arises on the call to Execute() in

ITemplate.Run(ExecuteContext context)

The stack trace reads as thus:

[NotImplementedException: The method or operation is not implemented.]
System.Web.HttpContextBase.get_Items() +29
System.Web.Mvc.Html.TemplateHelpers.GetActionCache(HtmlHelper html) +93
System.Web.Mvc.Html.TemplateHelpers.ExecuteTemplate(HtmlHelper html, ViewDataDictionary viewData, String templateName, DataBoundControlMode mode, GetViewNamesDelegate getViewNames, GetDefaultActionsDelegate getDefaultActions) +132
System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData, ExecuteTemplateDelegate executeTemplate) +1646
System.Web.Mvc.Html.TemplateHelpers.TemplateHelper(HtmlHelper html, ModelMetadata metadata, String htmlFieldName, String templateName, DataBoundControlMode mode, Object additionalViewData) +94
System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper`1 html, Expression`1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData, TemplateHelperDelegate templateHelper) +228
System.Web.Mvc.Html.TemplateHelpers.TemplateFor(HtmlHelper`1 html, Expression`1 expression, String templateName, String htmlFieldName, DataBoundControlMode mode, Object additionalViewData) +140
System.Web.Mvc.Html.EditorExtensions.EditorFor(HtmlHelper`1 html, Expression`1 expression) +93
CompiledRazorTemplates.Dynamic.aadebbaabbddd.Execute() +329
RazorEngine.Templating.TemplateBase.RazorEngine.Templating.ITemplate.Run(ExecuteContext context) in c:\_git\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateBase.cs:126
RazorEngine.Templating.TemplateService.Run(ITemplate template, DynamicViewBag viewBag) in c:\_git\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:608
RazorEngine.Templating.TemplateService.Parse(String razorTemplate, Object model, DynamicViewBag viewBag, String cacheName) in c:\_git\RazorEngine\src\Core\RazorEngine.Core\Templating\TemplateService.cs:439
RazorEngine.Razor.Parse(String razorTemplate, T model) in c:\_git\RazorEngine\src\Core\RazorEngine.Core\Razor.cs:263
TestRazorEngine.Controllers.AccountController.Test() in c:\~\TestRazorEngine\Controllers\AccountController.cs:47
2

There are 2 answers

0
VictorySaber On BEST ANSWER

The reason for this is that there was no HttpContext or WebPageContext in the my Html Template. I've answered this over in Calling RazorEngine.Parse() in Controller Action fails with bad HttpContextBase with code, but essentially you must call a controller action as usual (return PartialView(model)). In the .cshtml call RenderAction() specifying another controller action which gets the model and calls RazorEngine with the template (in my case just a string).

This way the context is completely fine for MVC to use when RazorEngine calls into it from Execute().

3
theLaw On

The EditorFor need a folder in your subview folder called EditorTemplates, so you have a directory tree like this /Views/yourViews/EditorTemplates i give you an example

in the main view

@Html.EditorFor(m => m.Destinatario)

in the subfolder the file Destinatario.cshtml

@model Domain.Models.Entities.Destinatario

<div class="item-destinatario">
<span data-action="view-destinatario">@Model.Nome</span>    

@Html.HiddenFor(m=>m.Id)
@Html.HiddenFor(m=>m.Tabella)
@Html.HiddenFor(m => m.Nome)
</div>

Edit: i forgot the model

public class Destinatario
{
    public int Id { get; set; }
    public string Tabella { get; set; }
    public string Nome { get; set; }
    public string Email { get; set; }
    public string Cellulare { get; set; }
    public string Fax { get; set; }
}