我有一个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方法中。
我无法将这些内容放入文件中,因为我将在运行时将它们组装起来。
提前谢谢!
答案 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);
}