Компиляция искрового выражения в строке - PullRequest
1 голос
/ 18 февраля 2011

У меня есть приложение 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());
    }

У меня был успех, если я создал файл Index.spark в папке Views, используя System.Web.Mvc.ViewEngines, и использовал оттуда HtmlHelpers, поэтому япредполагаю, что что-то мне не хватает в настройке моего SparkViewEngine в методе Index выше.

Я не могу поместить это содержимое в файл, так как буду собирать их во время выполнения.

Заранее спасибо!

Ответы [ 3 ]

0 голосов
/ 19 февраля 2011

Мне удалось найти работоспособное решение (подводные камни еще не обнаружены). Я использовал существующий SparkViewEngine из Mvc.ViewEngines и временно заменил его свойство ViewFolder на InMemoryViewFolder. Он сделал свое дело:

    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);            
    }
0 голосов
/ 02 марта 2011

В этом случае я бы осторожно управлял зарегистрированным движком Spark View. Я не уверен, какие побочные эффекты вы увидите, поменяв местами другой видоискатель.

Я делаю что-то похожее для рендеринга динамических представлений - хотя это в 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);
}
0 голосов
/ 18 февраля 2011

Вам нужно добавить пространства имен / сборки в движок Spark, он не добавляет автоматически System.Web и другие (вы создаете его вручную и вам нужно указать все настройки вручную, он не будет читать web.config).Также вам нужно будет предоставить HttpContext, потому что HtmlHelper не будет работать без него.Извините, я не могу сейчас вспомнить подробно, как это все должно быть сделано, см. здесь , как настроить сборки / пространства имен.

Но будет намного проще, если вы предоставите представление данных (представлениемодель) вместо.Либо передайте базовый URL-адрес в качестве параметра, либо передайте функцию (метод модели представления, Func <>), которую это представление вызовет для создания необходимого URL-адреса.Другой способ - указать основной шаблон для вашего движка в памяти, который будет переопределять все сущности, то есть будет устанавливать Html для вашего пользовательского MemoryHtmlHelper, который будет содержать такие же методы, как ActionLink, но будет работать без HttpContext.

...