-1

My requirement is to fetch html data from database and render it on view. But if that string contains @Html.Action("actionName","controllerName"), i need to call perticular controller action method also.

I am rendering my html on view using @Html.Raw().

Eg: Below is the html string stored in my database

'<h2> Welcome To Page </h2> <br/> @Html.Action("actionName", "controllerName")'

So when it render the string, it execute mentioned controller and action too.

Any help will be appreciated.

1 Answers1

0

You can try RazorEngine to allow string template in razor executed.

For example, sample code from the project site http://antaris.github.io/RazorEngine/:

using RazorEngine;
using RazorEngine.Templating; // For extension methods.

string template = "Hello @Model.Name, welcome to RazorEngine!";
var result =
    Engine.Razor.RunCompile(template, "templateKey", null, new { Name = "World" });

But there is one catch, Html and Url helpers are defined in the Mvc framework, hence it is not supported by default.

I will suggest you try to create your template by passing model so that you don't have to use @Html.Action.

If you can not avoid it, then there is possible a solution suggested by another so answer https://stackoverflow.com/a/19434112/2564920:

[RequireNamespaces("System.Web.Mvc.Html")]
public class HtmlTemplateBase<T>:TemplateBase<T>, IViewDataContainer
{
    private HtmlHelper<T> helper = null;
    private ViewDataDictionary viewdata = null;       

    public HtmlHelper<T> Html
    {
        get
        {
            if (helper == null) 
            {                  
                var writer = this.CurrentWriter; //TemplateBase.CurrentWriter
                var context = new ViewContext() { RequestContext = HttpContext.Current.Request.RequestContext, Writer = writer, ViewData = this.ViewData };

                helper = new HtmlHelper<T>(vcontext, this);
            }
            return helper;
        }
    }

    public ViewDataDictionary ViewData
    {
        get
        {
            if (viewdata == null)
            {
                viewdata = new ViewDataDictionary();
                viewdata.TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = string.Empty };

                if (this.Model != null)
                {
                    viewdata.Model = Model;
                }
            }
            return viewdata;
        }
        set
        {
            viewdata = value;
        }
    }

    public override void WriteTo(TextWriter writer, object value)
    {
        if (writer == null)
            throw new ArgumentNullException("writer");

        if (value == null) return;

        //try to cast to RazorEngine IEncodedString
        var encodedString = value as IEncodedString;
        if (encodedString != null)
        {
            writer.Write(encodedString);
        }
        else
        {
            //try to cast to IHtmlString (Could be returned by Mvc Html helper methods)
            var htmlString = value as IHtmlString;
            if (htmlString != null) writer.Write(htmlString.ToHtmlString());
            else
            {
                //default implementation is to convert to RazorEngine encoded string
                encodedString = TemplateService.EncodedStringFactory.CreateEncodedString(value);
                writer.Write(encodedString);
            }

        }
    }
} 

Then you have to use HtmlTemplateBase (modified base on https://antaris.github.io/RazorEngine/TemplateBasics.html#Extending-the-template-Syntax):

var config = new TemplateServiceConfiguration();
// You can use the @inherits directive instead (this is the fallback if no @inherits is found).
config.BaseTemplateType = typeof(HtmlTemplateBase<>);
using (var service = RazorEngineService.Create(config))
{
    string template = "<h2> Welcome To Page </h2> <br/> @Html.Action(\"actionName\", \"controllerName\")";

    string result = service.RunCompile(template, "htmlRawTemplate", null, null);
}

in essence, it is telling the RazorEngine to use a base template where mvc is involved, so that Html and Url helper can be used.

Community
  • 1
  • 1
Alan Tsai
  • 2,465
  • 1
  • 13
  • 16