在运行时渲染@ Html.Action(" actionName"," controllerName"),从MVC4中的数据库中获取

时间:2016-03-03 12:47:32

标签: asp.net-mvc-4

我的要求是从数据库中获取html数据并在视图中呈现它。但是如果该字符串包含@ Html.Action(" actionName"," controllerName"),我还需要调用特定控制器操作方法。

我使用 @ Html.Raw()在视图上渲染我的HTML。

例如:下面是存储在我的数据库中的html字符串

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

因此,当它呈现字符串时,它也会执行提到的控制器和操作。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以尝试RazorEngine在razor中执行字符串模板。

例如,项目网站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" });

但是有一个问题,Html和Url助手是在Mvc框架中定义的,因此默认情况下不支持。

我建议您尝试通过传递模型来创建模板,这样就不必使用@ Html.Action。

如果你无法避免,那么有可能是另一个人提出的解决方案,所以回答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);
            }

        }
    }
} 

然后你必须使用HtmlTemplateBase(在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);
}

实质上,它告诉RazorEngine使用涉及mvc的基本模板,以便可以使用Html和Url助手。