【问题标题】:Compiling a spark expression within a string在字符串中编译火花表达式
【发布时间】:2011-02-17 21:02:19
【问题描述】:

我有一个 ASP.NET MVC2 应用程序,我在其中尝试使用 Spark 视图引擎从输入字符串呈现,例如:

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

我在尝试使用 HtmlHelpers 时遇到了问题。 spark编译器返回错误'The name 'Html' does not exist in the current context'。完整方法如下:

    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());
    }

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

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

提前感谢您!

【问题讨论】:

    标签: spark-view-engine


    【解决方案1】:

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

    但是如果你提供一个视图数据(视图模型)会容易得多。要么将基本 url 作为参数传递,要么传递视图将调用以构造所需 URL 的函数(视图模型的方法,Func)。另一种方法是为您的内存引擎指定主模板,该模板将重新定义所有实体,即将 Html 设置为您的自定义 MemoryHtmlHelper,该模板将包含相同的方法,例如 ActionLink,但在没有 HttpContext 的情况下也可以工作。

    【讨论】:

      【解决方案2】:

      我能够找到一个可行的解决方案(尚未发现的陷阱)。我使用了 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);            
          }
      

      【讨论】:

        【解决方案3】:

        在这种情况下,我会小心操作已注册的 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);
        }
        

        【讨论】:

          猜你喜欢
          • 2020-12-09
          • 2021-07-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-05
          • 1970-01-01
          • 2019-04-10
          • 1970-01-01
          相关资源
          最近更新 更多