@Html

2011-12-19 15 views
24

के साथ 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 साइट पर देखा है:

Unable to compile template. The name 'Html' does not exist in the current context

यह दृश्य है कि मार्कअप renders है @Html का उपयोग (मुझे पता है कि वहां का संस्करण पुराना है और मुझे अपना संस्करण न्यूजेट के माध्यम से मिला है)।

इस पर कोई मदद महान होगी।

+0

मैं इस प्रश्न का उत्तर प्रस्तुत हैं तो उसे डुप्लिकेट जवाब के रूप में, क्योंकि मैं भी इसे यहाँ जवाब हटा दिया गया था: http://stackoverflow.com/questions/23603593/... ... इस जवाब दोनों के लिए काम करता एमवीसी और रेजरइंजिन। –

उत्तर

17

Html और Url सहायक गुण एमवीसी के उनके व्यू इंजन में रेज़र के कार्यान्वयन की वास्तविक विशेषताएं हैं। बॉक्स के बाहर, Html और Url वर्तमान में कस्टम बेस टेम्पलेट को विशेषज्ञता के बिना समर्थित नहीं हैं।

आगामी वी 3 रिलीज के साथ एक संबंधित RazorEngine.Web रिलीज होगा, जिसमें उम्मीद है कि Html और Url समर्थन के साथ एक एमवीसी 3 संगत आधार टेम्पलेट शामिल होगा।

प्रोजेक्ट होमपेज पर मैंने जो उदाहरण लिखा था, वह पूरी तरह कस्टम कस्टम टेम्पलेट का उपयोग करने का एक उदाहरण है।

आपको कम से https://github.com/Antaris/RazorEngine

+0

उत्तर के लिए धन्यवाद, क्या आपके पास एक विशेष आधार टेम्पलेट को परिभाषित करने के लिए एक उदाहरण या एक लिंक है, क्योंकि मुझे वास्तव में अब इस विकल्प की आवश्यकता है, और बाद में इसे बाद में उपयोग करने के लिए मैं इसे बदल सकता हूं? धन्यवाद फिर से – JamesStuddart

+0

मैंने http://razorengine.codeplex.com/wikipage?title=Building%20Custom%20Base%20 टेम्पलेट्स पर देखा है, लेकिन मुझे nuget से प्राप्त संस्करण में SetTemplateBase विधि नहीं है? – JamesStuddart

+1

वर्तमान में, हम Nuget पर v3.0.5beta रिलीज को दबा रहे हैं, आप 'इंस्टॉल-पैकेज RazorEngine -Version 2.1' का उपयोग कर पुराने v2.1 रिलीज़ को इंस्टॉल कर सकते हैं। V3 में बहुत कुछ बदल गया है जो आपके पुराने कोड को आपके पुराने v2.1 –

27

चेक https://github.com/Antaris/RazorEngine/wiki/6.-Encoding-Values पेज v3 के बारे में और अधिक जानकारी प्राप्त कर सकते हैं। मैं इसे कॉपी/पेस्ट करता हूं:

डिफ़ॉल्ट रूप से, 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!" 
+0

में वर्णित अनुसार एन्कोड किया गया है! '@Raw (स्ट्रिंग) 'विधि मेरे लिए क्या काम करती है,' IHtmlString' या अन्य कामकाज की आवश्यकता नहीं है। –

+0

एक आकर्षण की तरह काम करता है, thx ... –

9

यह खत्म हो गया है एक वर्ष पुराना है, लेकिन चूंकि मुझे इंटरनेट पर कहीं भी एक कामकाजी प्रति नहीं मिली है और जिथब पेज निष्क्रिय है, मुझे लगा कि मैं अपने कार्यान्वयन को @Html सहायक सिंटैक्स को RazorEngine में जोड़ने के लिए साझा करूंगा। यहां शुरुआती बिंदु के रूप में Abu Haider's implementation का उपयोग करके कार्यान्वित किया गया है।

माइक्रेटैश की टिप्पणी की सौजन्य: यदि आप @ 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); 
      } 

     } 
    } 
} 

मैं भी TemplateBase की WriteTo विधि ओवरराइड करने के लिए क्योंकि अन्यथा RazorEngine एन्कोड html जाएगा सहायक विधि का परिणाम जिसका अर्थ है आप बच जाएगा '<', '>' था, और उद्धरण (this question देखना)।एन्कोडिंग करने से पहले ओवरराइड IHtmlString मान के लिए एक चेक जोड़ता है।

+4

गरीब आत्मा जो यहां आती है यह पता लगाने की कोशिश कर रही है कि एचटीएमएल कैसे प्राप्त करें। RazorEngine के साथ काम करने के लिए आपको अनुरोध कॉन्टेक्स्ट जोड़ने की आवश्यकता है। 'वर संदर्भ = नए ViewContext() { RequestContext = HttpContext.Current.Request.RequestContext, लेखक = लेखक, ViewData = this.ViewData };' – miketrash

+0

@miketrash: जानकारी के लिए धन्यवाद! मुझे लगता है कि किसी बिंदु पर यह पता लगाना लेकिन इसका उपयोग नहीं किया क्योंकि मुझे किसी भी अनुरोध संदर्भ के बाहर फ़ाइलों को ऑफ़लाइन संकलित करने की आवश्यकता है। – mao47

+0

'Html.BeginForm' से आउटपुट अभी भी एन्कोड किया गया है। क्या कुछ अन्य लिखने की विधि भी ओवरराइड होनी चाहिए या क्या कोई अन्य समाधान है? यह http://stackoverflow.com/questions/41531298/how-to-render-html-beginform-output-unescaped में पोस्ट किया गया है। 'encodedString = TemplateService.EncodedStringFactory.CreateEncodedString (मान); 'कंपाइलर चेतावनी का उत्पादन करता है' टेम्पलेटबेस। टेम्पलेट सेवा अप्रचलित है – Andrus

4

मेरी माफ़ी, मेरे पास कोई टिप्पणी जोड़ने के लिए आवश्यक 50 प्रतिष्ठा नहीं है इसलिए जवाब देना होगा।

यदि कोई सोच रहा है (जैसा कि जेम्सस्टुडार्ट था) 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); 
     } 
11

यह काफी पुराना सवाल है, लेकिन मैं coderwall पर अच्छा जवाब मिल गया।

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

या बस:

@(new RawString(Model.YourHTMLStrinInModel)) 

मुझे आशा है कि यह उपयोगी है समाधान का उपयोग करने के लिए है।

+1

यह - वेब कॉन्फ़िगर में ' जोड़ें, अगर आप इसे होस्ट कर रहे हैं इंटेलिजेंस प्राप्त करने के लिए कक्षा पुस्तकालय/विनफॉर्म इत्यादि। – GJKH

+0

RazorEngine v.3.9.3 का उपयोग करना। यह मेरे लिए काम नहीं करता है। मुझे 'RawString' त्रुटि प्राप्त नहीं है। – codeMonkey

0

नवीनतम रेज़र सिंटैक्स के लिए माओ 47 उत्तर का संशोधन, यह आंशिक विचारों का भी समर्थन करेगा।

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

       } 

      } 
     } 
    } 
} 
संबंधित मुद्दे