35

私はRazorEngineを使用して、いくつかの基本的なコンテンツ(非常に大雑把なコンテンツ管理システム)をレンダリングしています。

@Html構文をマークアップに含めるまではうまく機能します。

マークアップに@htmlが含まれている場合、次のエラーが発生します。

テンプレートをコンパイルできません。「Html」という名前は現在のコンテキストには存在しません

これは、マークアップをレンダリングするビューです。

@Model Models.ContentPage

@{
    ViewBag.Title = Model.MetaTitle;
    Layout = "~/Views/Shared/Templates/_" + Model.Layout + "Layout.cshtml";

}
@Html.Raw(RazorEngine.Razor.Parse(Model.Markup, Model))

私はRazorEngineのCodeplexサイトで@Htmlの使用を見てきました(そこにあるバージョンが古くなっていることを知っていて、nuget経由でバージョンを取得しました)。

これに関するどんな助けも素晴らしいでしょう。

4

8 に答える 8

31

https://github.com/Antaris/RazorEngine/wiki/6.-Encoding-Valuesページを確認してください。ここにコピー/貼り付けます:

デフォルトでは、RazorEngineはHTMLとしてエンコードするように構成されています。これにより、出力をそのままにしたいときに特定の文字がHTMLとしてエンコードされるという問題が発生することがあります。

生の形式で何かを出力するには、次の例に示すように、@ Raw()組み込みメソッドを使用します。

string template = "@Raw(Model.Data)";
var model = new { Data = "My raw double quotes appears here \"hello!\"" };

string result = Razor.Parse(template, model);

結果は次のようになります。

My raw double quotes appears here "hello!"
于 2012-07-30T11:05:37.773 に答える
19

およびヘルパープロパティはHtmlUrlMVCによるビューエンジンでのRazorの実装の実際の機能です。箱から出して、カスタムベーステンプレートを特殊Html化せUrlずに現在サポートされていません。

今後のv3リリースには、関連するRazorEngine.Webリリースが付属します。これには、MVC3互換のベーステンプレートHtmlUrlサポートが含まれることを願っています。

私がプロジェクトのホームページに書いた例は、純粋にカスタムベーステンプレートを使用した例です。

v3の詳細については、https://github.com/Antaris/RazorEngineをご覧ください。

于 2011-12-19T13:39:53.540 に答える
13

これは1年以上前のことですが、インターネット上で作業コピーが見つからず、githubページが非アクティブであるため、実装を共有して@Htmlヘルパー構文をRazorEngineに追加することにしました。これが、 AbuHaiderの実装を出発点として使用して最終的に作成した実装です。

miketrashのコメントの礼儀:@ Html.Action()を使用しようとしている場合は、RequestContextを追加する必要があります(を使用できますHttpContext.Current.Request.RequestContext)。アプリケーションで常に使用できるとは限らないため、リクエストコンテキストは含めませんでした。

[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 vcontext = new ViewContext() { 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);
            }

        }
    }
}

WriteToまた、のメソッドをオーバーライドする必要がありましTemplateBaseた。そうしないと、RazorEngineがヘルパーメソッドの結果をhtmlエンコードするため、「<」、「>」、および引用符をエスケープします(この質問を参照)。IHtmlStringオーバーライドは、エンコーディングの実行に頼る前に、値がであるかどうかのチェックを追加します。

于 2013-10-17T18:10:22.253 に答える
13

かなり古い質問ですが、 coderwallで良い答えを見つけました。解決策は次を使用することです。

@(new RawString("<strong>Bold!</strong>"))

あるいは単に:

@(new RawString(Model.YourHTMLStrinInModel))

お役に立てば幸いです。

于 2014-07-31T07:42:35.390 に答える
5

申し訳ありませんが、コメントを追加するために必要な50の評判がないため、回答を入力する必要があります。

(JamesStuddartがそうであったように)誰かが疑問に思っている場合は、SetTemplateBase()メソッドがありませんが、基本テンプレートを使用してサービスを初期化するための構成インスタンスを作成できます。

http://razorengine.codeplex.com/discussions/285937から、次のようにコードを調整しました。

var config = new RazorEngine.Configuration.TemplateServiceConfiguration
        {
            BaseTemplateType = typeof(MyHtmlTemplateBase<>)
        };

        using (var service = new RazorEngine.Templating.TemplateService(config))
        {
            // Use template service.
            Razor.SetTemplateService(service);
            result = Razor.Parse(templateString, model);
        }
于 2013-12-11T15:21:14.383 に答える
3

Html.Raw最も単純なソリューション!! 必要な3つのステップ

ステップ1:TemplateBaseから継承します。

public class HtmlSupportTemplateBase<T> : TemplateBase<T>
{
    public HtmlSupportTemplateBase()
    {
        Html = new MyHtmlHelper();
    }

    public MyHtmlHelper Html { get; set; }

}

ステップ2:テンプレートで使用されるすべてのHtmlメソッドを利用できるようにするオブジェクトを作成します。この例では、Html.RawとHtml.Encodeがcshtmlで使用可能になります。レンプレート

public class MyHtmlHelper
{
    /// <summary>
    /// Instructs razor to render a string without applying html encoding.
    /// </summary>
    /// <param name="htmlString"></param>
    /// <returns></returns>
    public IEncodedString Raw(string htmlString)
    {
        return new RawString(htmlString);
    }

    public string Encode(string value)
    {
        return System.Net.WebUtility.HtmlEncode(value);
    }

    public string Encode(object value)
    {
        return "do whatever";
    }
}

ステップ3:

var config = new TemplateServiceConfiguration
{
    TemplateManager = templateManager,
    BaseTemplateType = typeof(HtmlSupportTemplateBase<>)
};
于 2018-05-09T07:24:39.023 に答える
3

の答えは、hannesneukermansによる答えを使用しています。

管理者ユーザーが編集できるように、データベースに保存されているhtml文字列を組み込んだ電子メールをRazorEngineを使用して送信する必要がありました。

標準の設定では、@Html.Rawが機能しませんでした。

メールクラスでは、Hannesが推奨するクラスを組み込んだ新しいEngine.Razor(エンジンは静的)を設定しました。Rawメソッドのみが必要でしたが、他のメソッドを追加することもできます。

    public class HtmlSupportTemplateBase<T> : TemplateBase<T>
{
    public HtmlSupportTemplateBase()
    {
        Html = new MyHtmlHelper();
    }
    public MyHtmlHelper Html { get; set; }
}  

 public class MyHtmlHelper
{
    /// <summary>
    /// Instructs razor to render a string without applying html encoding.
    /// </summary>
    /// <param name="htmlString"></param>
    /// <returns></returns>
    public IEncodedString Raw(string htmlString)
    {
        return new RawString(WebUtility.HtmlEncode(htmlString));
    } 
}

次に、メールテンプレートで@ Html.Rawを使用して、編集可能なhtmlを組み込むことができます。

public class Emails
{
    public static TemplateServiceConfiguration config 
                = new TemplateServiceConfiguration(); // create a new config

    public Emails()
    {   
        config.BaseTemplateType = typeof(HtmlSupportTemplateBase<>);// incorporate the Html helper class
        Engine.Razor = RazorEngineService.Create(config);// use that config to assign a new razor service
    }

    public static void SendHtmlEmail(string template,  EmailModel model)
    {           
        string emailBody 
             = Engine.Razor.RunCompile(template, model.Type.ToString(), typeof(EmailModel), model);

以下は実際には答えの一部ではありませんが、電子メールにそれを使用している人に役立つコードを提供します:)

        var smtpClient = getStaticSmtpObject(); // an external method not included here     
        MailMessage message = new MailMessage();
        message.From = new MailAddress(model.FromAddress);
        message.To.Add(model.EmailAddress); 
        message.Subject = model.Subject;
        message.IsBodyHtml = true;
        message.Body =  System.Net.WebUtility.HtmlDecode(emailBody);
        smtpClient.SendAsync(message, model); 
    }
}

次に、実際の.cshtmlテンプレートから読み取った文字列と、電子メールデータを保持しているモデルを渡すことで使用できます。(ResolveConfigurationPathは、このページで見つけたもう1つの外部関数です)

string template = System.IO.File.ReadAllText(ResolveConfigurationPath("~/Views/Emails/MAPEmail.cshtml"));
SendHtmlEmail(template, model);
于 2019-01-23T03:33:27.747 に答える
1

最新のかみそり構文に対するmao47の回答の変更。これは、一部のメソッドを再作成するだけでなく、MicrosoftのヘルパーをSystem.Web.Mvc.dllから取得するため、部分ビューや他の多くのヘルパーメソッドもサポートします。

    using System;
    using System.Collections.Concurrent;
    using System.IO;
    using System.Linq;
    using System.Web.Hosting;
    using System.Xml.Linq;
    using RazorEngine.Configuration;
    using RazorEngine.Templating;
    public static class DynamicRazorTemplateParser
        {
            private static readonly IRazorEngineService service = RazorEngineService.Create(TemplateServiceConfiguration);
            public static string RunCompile<T>(string template, string placeholder, T model, DynamicViewBag viewBag) where T : class
            {
                var templateSource = new LoadedTemplateSource(template);
                return RunCompile(templateSource, placeholder, model, viewBag);
            }
            public static string RunCompile<T>(ITemplateSource template, string placeholder, T model, DynamicViewBag viewBag) where T : class 
            {            
                    return service.RunCompile(template, placeholder, model.GetType(), model, viewBag);
            }
            public static string RunCompile(ITemplateSource template, string placeholder)
            {
    
                
                    return service.RunCompile(template, placeholder);
                
            }
    
            private static TemplateServiceConfiguration TemplateServiceConfiguration
            {
                get
                {
                    var config = new TemplateServiceConfiguration
                    {
                        BaseTemplateType = typeof(HtmlTemplateBase<>),
                        TemplateManager = new TemplateManager()
                    };
                    //TODO: Is this the best way?
                    var xDocument = XDocument.Load(AppDomain.CurrentDomain.SetupInformation.ApplicationBase + "/Views/Web.config");
                    if (xDocument.Root != null)
                    {
                        var sysWeb = xDocument.Root.Element("system.web.webPages.razor");
                        if (sysWeb == null) return config;
                        var pages = sysWeb.Element("pages");
                        if (pages != null)
                        {
                            var namespaces = pages.Element("namespaces");
                            if (namespaces != null)
                            {
                                var namespacesAdd = namespaces.Elements("add")
                                    .Where(x => x.Attribute("namespace") != null)
                                    .Select(x =>
    
                                        x.Attribute("namespace").Value
                                    );
                                foreach (var ns in namespacesAdd)
                                {
                                    config.Namespaces.Add(ns);
                                }
                            }
                        }
                    }
                    return config;
                }
            }
            private class TemplateManager : ITemplateManager
            {
                private readonly ConcurrentDictionary<ITemplateKey, ITemplateSource> _dynamicTemplates = new ConcurrentDictionary<ITemplateKey, ITemplateSource>();
                private readonly string baseTemplatePath;
                public TemplateManager()
                {
                    baseTemplatePath = HostingEnvironment.MapPath("~/Views/");
                }
    
                public ITemplateSource Resolve(ITemplateKey key)
                {
                    ITemplateSource templateSource;
                    if (this._dynamicTemplates.TryGetValue(key, out templateSource))
                        return templateSource;
    
                    string template = key.Name;
                    var ubuilder = new UriBuilder();
                    ubuilder.Path = template;
                    var newURL = ubuilder.Uri.LocalPath.TrimStart('/');
                    string path = Path.Combine(baseTemplatePath, string.Format("{0}", newURL));
    
    
                    string content = File.ReadAllText(path);
                    return new LoadedTemplateSource(content, path);
                }
    
                public ITemplateKey GetKey(string name, ResolveType resolveType, ITemplateKey context)
                {
                    return new NameOnlyTemplateKey(name, resolveType, context);
                }
    
                public void AddDynamic(ITemplateKey key, ITemplateSource source)
                {
                    this._dynamicTemplates.AddOrUpdate(key, source, (k, oldSource) =>
                    {
                        if (oldSource.Template != source.Template)
                            throw new InvalidOperationException("The same key was already used for another template!");
                        return source;
                    });
                }
            }
        }

    using System;
    using System.IO;
    using System.Web;
    using System.Web.Mvc;
    using System.Web.Routing;
    using RazorEngine.Templating;
    using RazorEngine.Text;
    // ReSharper disable ClassWithVirtualMembersNeverInherited.Global
    // ReSharper disable MemberCanBePrivate.Global

    namespace Common.Core.Razor
    {
        [RequireNamespaces("System.Web.Mvc.Html")]
        public class HtmlTemplateBase<T> : RazorEngine.Templating.HtmlTemplateBase<T>, IViewDataContainer
        {
            private HtmlHelper<T> helper;
            private ViewDataDictionary viewdata;
            private TempDataDictionary tempdata;
            private AjaxHelper<T> ajaxHelper;
            private ViewContext viewContext;
            private UrlHelper urlHelper;
            private readonly RequestContext _requestContext = HttpContext.Current.Request.RequestContext;
    
    
            public UrlHelper Url => urlHelper ?? (urlHelper = new UrlHelper(_requestContext));
    
            public ViewContext ViewContext
            {
                get
                {
                    if (viewContext != null) return viewContext;
                    viewContext = GetViewContext();
                    return viewContext;
                }
            }
    
            public AjaxHelper<T> Ajax
            {
                get
                {
                    if (ajaxHelper != null) return ajaxHelper;
                    ajaxHelper = new AjaxHelper<T>(ViewContext, this);
                    return ajaxHelper;
                }
            }
    
            public HtmlHelper<T> Html
            {
                get
                {
                    if (helper != null) return helper;
                    helper = new HtmlHelper<T>(ViewContext, this);
                    return helper;
                }
            }
    
            public ViewDataDictionary ViewData
            {
                get
                {
                    if (viewdata == null)
                    {
                        viewdata = new ViewDataDictionary
                        {
                            TemplateInfo = new TemplateInfo() { HtmlFieldPrefix = string.Empty }
                        };
    
                        if (Model != null)
                        {
                            viewdata.Model = Model;
                        }
                    }
                    return viewdata;
                }
                set
                {
                    viewdata = value;
                }
            }
            public TempDataDictionary TempData
            {
                get { return tempdata ?? (tempdata = new TempDataDictionary()); }
                set
                {
                    tempdata = value;
                }
            }
            public virtual string RenderView()
            {
                using (var writer = new StringWriter())
                {
                    ViewContext.View.Render(ViewContext, CurrentWriter);
                    return writer.GetStringBuilder().ToString();
                }
            }
    
    
            private ViewContext GetViewContext()
            {
                if (HttpContext.Current == null) throw new NotImplementedException();
                var requestContext = _requestContext;
                var controllerContext = ControllerContext(requestContext);
    
                var view = GetView(requestContext, controllerContext);
                //Can't check if string writer is closed, need to catch exception
                try
                {
                    var vContext = new ViewContext(controllerContext, view, ViewData, TempData, CurrentWriter);
                    return vContext;
    
                }
                catch
                {
                    using (var sw = new StringWriter())
                    {
                        var vContext = new ViewContext(controllerContext, view, ViewData, TempData, sw);
                        return vContext;
                    }
                }
            }
    
            private IView GetView(RequestContext requestContext, ControllerContext controllerContext)
            {
                if ((string)requestContext.RouteData.DataTokens["Action"] != null)
                {
                    requestContext.RouteData.Values["action"] = (string)requestContext.RouteData.DataTokens["Action"];
                }
    
                var action = requestContext.RouteData.GetRequiredString("action");
                var viewEngineResult = ViewEngines.Engines.FindPartialView(controllerContext, action);
                if (viewEngineResult != null && viewEngineResult.View != null)
                {
                    return viewEngineResult.View;
                }
    
                viewEngineResult = ViewEngines.Engines.FindView(controllerContext, action, null);
                if (viewEngineResult == null)
                {
                    throw new Exception("No PartialView assigned in route");
                }
                return viewEngineResult.View;
    
    
            }
    
            public void SetView(string view)
            {
                _requestContext.RouteData.DataTokens["Action"] = view;
            }
    
    
            private ControllerContext ControllerContext(RequestContext requestContext)
            {
                ControllerBase controllerBase;
                var routeDataValue = "EmptyController";
                if (requestContext.RouteData.Values["controller"] != null && (string)requestContext.RouteData.Values["controller"] != routeDataValue)
                {
                    var controllerName = (string)requestContext.RouteData.Values["controller"];
                    IController controller = ControllerBuilder.Current.GetControllerFactory().CreateController(requestContext, controllerName);
                    controllerBase = controller as ControllerBase;
                }
                else
                {
    
                    var controller = new EmptyController();
                    controllerBase = controller; //ControllerBase implements IController which this returns
                    requestContext.RouteData.Values["controller"] = routeDataValue;
                }
                var controllerContext =
                    new ControllerContext(requestContext.HttpContext, requestContext.RouteData, controllerBase);
                return controllerContext;
            }
            private class EmptyController : Controller { }
            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
                        base.WriteTo(writer, value);
    
                    }
    
                }
            }
        }
    }
于 2017-05-12T15:18:20.037 に答える