⬆️ ⬇️

Using Razor separately from ASP.NET MVC

By the nature of my activity as a student, I often have to write various laboratory and term papers. An integral part of this work (as in 80% of business programming tasks) is the code for generating a report on the items found in the database or on a long and complex operation. There are various ways to solve such problems in desktop programming within the .NET Framework:



I'll talk about the latter.



The simplest and most obvious option is to manually format the HTML string. Those who are just introduced to the platform will immediately begin to deal with the concatenation of String objects, who have read the documentation and will pay attention to the StringBuilder class. In any case, String.Format is not always the most convenient way to generate reports. On the other hand, platform colleagues using ASP.NET MVC cannot rejoice at the Razor view engine . And then the question arises: why not use the power of ASP.NET Razor for their own purposes?

First of all, you need to connect the assembly System.Web.Razor . It is from the ASP.NET MVC distribution, so if the target computer does not have it installed, you should take care of the local copying of the necessary dlls.

Let's declare the base class from which our view will be inherited.

public abstract class TemplateBase { public StringBuilder Buffer { get; set; } public StringWriter Writer { get; set; } public TemplateBase() { Buffer = new StringBuilder(); Writer = new StringWriter(Buffer); } public abstract void Execute(); //     : "@foo.Bar" public virtual void Write(object value) { // Don't need to do anything special // Razor for ASP.Net does HTML encoding here. WriteLiteral(value); } //   : "<p>Foo</p>" public virtual void WriteLiteral(object value) { Buffer.Append(value); } // ...       -  ,     Razor    ,      } 


First of all, you need to initialize the engine.

 private RazorTemplateEngine SetupRazorEngine() { // 1. ,    C#   RazorEngineHost host = new RazorEngineHost(new CSharpRazorCodeLanguage()); // 2.   ,    .  ,    host.DefaultBaseClass = typeof(TemplateBase).FullName; // 3.        host.DefaultNamespace = "RazorOutput"; host.DefaultClassName = "Template"; // 4.       (using) host.NamespaceImports.Add("System"); // 5.     return new RazorTemplateEngine(host); } 


As you know, .NET supports code compilation on the fly. This feature and uses Razor. Therefore, in our case, it is necessary to read the file with the template and save it to a separate assembly.

  //    GeneratorResults razorResult = null; using (TextReader rdr = new StringReader( MyTemplatesString )) razorResult = _engine.GenerateCode(rdr); CSharpCodeProvider codeProvider = new CSharpCodeProvider(); //       string outputAssemblyName = String.Format("Temp_{0}.dll", Guid.NewGuid().ToString("N")); CompilerResults results = codeProvider.CompileAssemblyFromDom( new CompilerParameters(new string[] { typeof(Form1).Assembly.CodeBase.Replace("file:///", "").Replace("/", "\\") }, outputAssemblyName), razorResult.GeneratedCode); 


If everything went well, then further use is simple:

  Assembly asm = Assembly.LoadFrom(outputAssemblyName); if (asm == null) { MessageBox.Show("    "); } else { Type typ = asm.GetType("RazorOutput.Template"); if (typ == null) { MessageBox.Show("  RazorOutput.Template   {0}", asm.FullName); } else { TemplateBase newTemplate = Activator.CreateInstance(typ) as TemplateBase; if (newTemplate == null) { MessageBox.Show("   RazorOutput.Template     TemplateBase"); } else { //    newTemplate     // ... newTemplate.Execute(); string resultHTML = newTemplate.Buffer.ToString(); newTemplate.Buffer.Clear(); return resultHTML; //          String,      } } } 


That's all. The only question that remains is how to specify these views - via TemplateBase, or through the Razor-syntax of the form

 @functions { public string CustomerName { get; set; } public string ResetLink { get; set; } } 


In the latter case, you will have to abandon the dynamic generation of templates, but it is very easy to get access to this data.



So, with the help of simple movements, we have avoided the temptation of writing “another” template using the powerful and convenient tool from MS




1 assumes that once you write under the .NET Framework, it is assumed to be installed on the client. But Office, Crystal Reports, SQL Server, Visual Studio - not necessarily


')

Source: https://habr.com/ru/post/173923/



All Articles