在字符串中编译spark表达式

时间:2011-02-17 21:02:20

标签: spark-view-engine

我有一个ASP.NET MVC2应用程序,在其中我尝试使用Spark View Engine从输入字符串进行渲染,例如:

"!{Html.ActionLink(\"A Link\", \"Index\")} Followed by some text"

我在尝试使用HtmlHelpers时遇到了问题。 spark编译器返回错误'当前上下文中不存在名称'Html'。完整的方法如下:

    public ActionResult Index()
    {
        var templates = new InMemoryViewFolder();
        var engine = new SparkViewEngine() { ViewFolder = templates };

        var stringResult = new StringBuilder();
        stringResult.AppendLine("!{Html.ActionLink(\"A Link\", \"Index\")} Followed by some text");

        templates.Add("string.spark", stringResult.ToString());

        var descriptor = new SparkViewDescriptor().AddTemplate("string.spark");
        var view = engine.CreateInstance(descriptor);
        var result = new StringBuilder();
        StringWriter sw = new StringWriter(result);
        view.RenderView(sw);

        return Content(result.ToString());
    }

如果我使用System.Web.Mvc.ViewEngines在Views文件夹中创建一个Index.spark文件并使用HtmlHelpers,那么我已经取得了成功,所以我猜我的设置中缺少一些东西SparkViewEngine在上面的Index方法中。

我无法将这些内容放入文件中,因为我将在运行时将它们组装起来。

提前谢谢!

3 个答案:

答案 0 :(得分:0)

您需要向Spark引擎添加名称空间/程序集,它不会自动添加System.Web和其他程序(您手动构建它并且必须手动指定所有配置,它不会读取web.config)。此外,您还需要提供HttpContext,因为如果没有它,HtmlHelper将无法工作。抱歉现在不能详细记住如何完成这一切,请参考here如何设置程序集/命名空间。

但是,如果您提供视图数据(视图模型),则会更容易。将基本URL作为参数传递,或者传递视图将调用以构造所需URL的函数(视图模型的方法,Func<>)。另一种方法是,为你的内存引擎指定主模板,它将重新定义所有实体,即将Html设置为自定义MemoryHtmlHelper,它将包含相同的方法,如ActionLink,但不使用HttpContext。

答案 1 :(得分:0)

我能够找到一个可行的解决方案(陷阱还有待发现)。我使用了Mvc.ViewEngines中现有的SparkViewEngine,并使用InMemoryViewFolder临时替换了它的ViewFolder属性。它成功了:

    public ActionResult Index()
    {
        SparkViewFactory f = (SparkViewFactory)ViewEngines.Engines.First(x => x is SparkViewFactory);
        InMemoryViewFolder templates = new InMemoryViewFolder();
        templates.Add("string.spark", "${Html.ActionLink(\"Testing\", \"Index\")} Html Helpers");

        IViewFolder savedViewFolder = f.Engine.ViewFolder;
        f.Engine.ViewFolder = templates;
        SparkViewDescriptor descriptor = new SparkViewDescriptor().AddTemplate("string.spark");
        var view = (SparkView)f.Engine.CreateInstance(descriptor);

        f.Engine.ReleaseInstance(view);
        f.Engine.ViewFolder = savedViewFolder;

        return View(view, null);            
    }

答案 2 :(得分:0)

在这种情况下,我会小心操作已注册的Spark视图引擎。我不确定通过交换不同的ViewFolder你会看到什么副作用。

我正在做类似渲染动态视图的事情 - 虽然它在HtmlHelper中 - 所以我可以访问ViewContext:

public static void RenderDynamic(this HtmlHelper html)
{
    string dynamicViewContent = BuildDynamicSparkView();  //build your dynamic content here
    var descriptor = new SparkViewDescriptor().AddTemplate("sample.spark");

    var inMemoryViewFolder = new InMemoryViewFolder();
    inMemoryViewFolder.Add("sample.spark", dynamicViewContent);

    var sparkViewEngine = new SparkViewEngine();
    sparkViewEngine.ViewFolder = inMemoryViewFolder;

    var view = (SparkView)sparkViewEngine.CreateInstance(descriptor);
    view.Render(html.ViewContext, html.ViewContext.Writer);

    sparkViewEngine.ReleaseInstance(view);
}