рд░реЗрдЬрд░ рд╕реЗ рдкрд░реЗ ASP.NET рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛

рдЗрд╕рд▓рд┐рдП, рдХрд▓ Microsoft рдиреЗ ASP.NET MVC3 RTM рдЬрд╛рд░реА рдХрд┐рдпрд╛ , рдЬрд┐рд╕рдореЗрдВ рдирдпрд╛ рд░реЗрдЬрд╝рд░ рд╡реНрдпреВ рдЗрдВрдЬрди рд╢рд╛рдорд┐рд▓ рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рд╢рд╛рдпрдж рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрд╛рдирддреЗ рд╣реИрдВ, рд░реЗрдЬрд░ рдореЗрдВ рд╡реЗрдм рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ рдХреЛрдИ рдШрдЯрдХ рдирд╣реАрдВ рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЕрд░реНрде рд╣реИ рдХрд┐ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЕрдиреНрдп рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдЦреИрд░, рдЕрдЧрд░ рдЖрдк рдЕрднреА рднреА рдпрд╣ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рд╣реИрдВ - рддреЛ рдпрд╣ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХрд╛ рд╕рдордп рд╣реИ!



рдЗрд╕ рдкреЛрд╕реНрдЯ рдореЗрдВ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рд░реЗрдЬрд░ рдХреЛ рдЖрдкрдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдЗрд╕рдХрд╛ рд╕реНрд░реЛрдд рдПрдВрдбреНрд░рдпреВ рдирд░реНрд╕ рдХрд╛ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ "ASP.Net рдХреЗ рдмрд╛рд╣рд░ рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рд░реЗрдЬрд░" рдерд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдкреНрд░рддреНрдпрдХреНрд╖ рдЕрдиреБрд╡рд╛рдж рдирд╣реАрдВ рд╣реИред







рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рдЯреЗрдХреНрд╕реНрдЯ рд▓реЗрдЯрд░ рдмрдирд╛рдКрдВрдЧрд╛ рдЬрд┐рд╕рдореЗрдВ рдСрд░реНрдбрд░ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╣реЛрдЧреАред



рдПрдХ рдЖрджреЗрд╢ рджреЛ рд╡рд░реНрдЧреЛрдВ рджреНрд╡рд╛рд░рд╛ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдСрд░реНрдбрд░рдореЙрдбрд▓ рдФрд░ рдСрд░реНрдбрд░ рдЗрдЯреЗрдордореЙрдбрд▓:



public class OrderModel { public string FirstName { get; set; } public string LastName { get; set; } public List<OrderItemModel> Items { get; set; } } public class OrderItemModel { public string ProductName { get; set; } public Decimal Price { get; set; } public int Qty { get; set; } }
      
      







рдИ-рдореЗрд▓ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдореИрдВ рдЬрд┐рд╕ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реВрдВрдЧрд╛ рд╡рд╣ рдиреАрдЪреЗ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдк рд░реЗрдЬрд╝рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╡рд┐рд╕реНрддреГрдд рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдВрджреНрд░реЗрдИ рдЯрд░рд┐рддреНрд╕рд┐рди рдХреЗ рдмреНрд▓реЙрдЧ рдкреЛрд╕реНрдЯ рдореЗрдВ "рд░реЗрдЬрд╝рд░ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдХреНрд╡рд┐рдХ рд╕рдВрджрд░реНрдн [рдЕрдиреБрд╡рд╛рдж]" ред



 , @Model.FirstName @Model.LastName! #   -  - ---------- ------ ------ ------ @for (var i = 0; i < Model.Items.Count; i++) { var item = Model.Items[i]; @String.Format( "{0} {1,-10} {2,6} {3,6} {4,6}\r\n", i + 1, @item.ProductName, @item.Price, @item.Qty, item.Price * item.Qty) } : @(((OrderModel)Model).Items.Sum(x => x.Price * x.Qty)) WBR, ACME team
      
      







рдореБрдЭреЗ рдПрдХ рдРрд╕реЗ рд╡рд░реНрдЧ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдЬреЛ рдореЗрд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рд▓рд┐рдП рдЖрдзрд╛рд░ рдХреЗ рд░реВрдк рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛:



 public abstract class TemplateBase { public TextWriter Output { get; set; } public dynamic Model { get; set; } public abstract void Execute(); public virtual void Write(object value) { this.Output.Write(value); } public virtual void WriteLiteral(object value) { this.Output.Write(value); } }
      
      







рдЖрдЙрдЯрдкреБрдЯ рдЧреБрдг TextWriter рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рдЬреЛ рдЯреЗрдореНрдкрд▓реЗрдЯ рдирд┐рд╖реНрдкрд╛рджрди рдХрд╛ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИред



рдореЙрдбрд▓ рдкреНрд░реЙрдкрд░реНрдЯреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред



рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓реА рдХрдХреНрд╖рд╛ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрди () рдкрджреНрдзрддрд┐ рдореЗрдВ рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдХреЛрдб рд╣реЛрдЧрд╛ред



рд▓рд┐рдЦрдиреЗ () рдФрд░ WriteLiteral () рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреНрд░рдорд╢рдГ рдЖрдЙрдЯрдкреБрдЯ, рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐рдпреЛрдВ рдФрд░ рдкрд╛рда рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдореВрд▓реНрдпрд╛рдВрдХрди рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдХреНрдпреЛрдВрдХрд┐ рдореБрдЭреЗ рдЧрдгрдирд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╛ рд╕реНрдЯреНрд░рд┐рдВрдЧреНрд╕ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ; рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХрд╛ рдХреЛрдб рд╕рдорд╛рди рд╣реИред



рдиреЛрдЯ: рдирд╛рдо Execute (), Write (), рдФрд░ WriteLiteral () рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЖрдк RazorEngineHost рд╡рд░реНрдЧ рдХреА рдЖрд╡реГрддреНрддрд┐ рдХреЗ GeneratedClassContext рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдиреНрдп рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред



рдЕрдм рдореИрдВ рд░реЗрдЬрд░ рдХреЗ рд▓рд┐рдП рдПрдХ рдореЗрдЬрдмрд╛рди рдмрдирд╛рдКрдВрдЧрд╛, рдпрд╣ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ рдХрд┐ рдореЗрд░реЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдореЗрдВ C # рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдпрджрд┐ рд░реЗрдЬрд╝рд░ C # рдФрд░ VB рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдЖрдк VBRazorCodeLanguage рдХрд╛ RazorineineHost constructor рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдкрд╛рд░рд┐рдд рдХрд░рдХреЗ VB рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ):



 var razorHost = new RazorEngineHost(new CSharpRazorCodeLanguage());
      
      







рдЕрдЧрд▓рд╛, рдореИрдВ рдЖрдзрд╛рд░ рд╡рд░реНрдЧ рдХрд╛ рдирд╛рдо, рдирд╛рдо рд╕реНрдерд╛рди рдЬрд┐рд╕рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛрдб рд╕реНрдерд┐рдд рд╣реЛрдЧрд╛, рдФрд░ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╢реНрд░реЗрдгреА рдХрд╛ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рддрд╛ рд╣реВрдВ:



 razorHost.DefaultBaseClass = typeof(TemplateBase).FullName; razorHost.DefaultNamespace = "StandaloneRazorDemo"; razorHost.DefaultClassName = "Template";
      
      







рдЯреЗрдореНрдкрд▓реЗрдЯ рд╡рд░реНрдЧ рдХреЗ рдХреЛрдб рдореЗрдВ рдЙрдкрд▓рдмреНрдз рдирд╛рдорд╕реНрдерд╛рди рдХрд╛ рдПрдХ рд╕реЗрдЯ рдЬреЛрдбрд╝реЗрдВ:



 razorHost.NamespaceImports.Add("System"); razorHost.NamespaceImports.Add("System.Collections.Generic"); razorHost.NamespaceImports.Add("System.Linq"); razorHost.NamespaceImports.Add("System.Text");
      
      







рдФрд░ рдЕрдВрдд рдореЗрдВ, рдореИрдВ рдПрдХ рдЯреЗрдореНрдкрд▓реЗрдЯ рдЗрдВрдЬрди рдмрдирд╛рддрд╛ рд╣реВрдВ:



 var razorEngine = new RazorTemplateEngine(razorHost);
      
      







рдЕрдм рдореИрдВ рдЕрдкрдиреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛:



 var templateText = File.ReadAllText("template.txt"); GeneratorResults generatorResults = null; using (var reader = new StringReader(templateText)) { generatorResults = razorEngine.GenerateCode(reader); }
      
      







рдЬреЗрдирд░реЗрдЯрд░рд╕реВрдЯреНрд╕ рд╡рд░реНрдЧ рдХреА рд╕рдлрд▓рддрд╛ рд╕рдВрдкрддреНрддрд┐ рдЗрдВрдЧрд┐рдд рдХрд░рддреА рд╣реИ рдХрд┐ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХрд┐рддрдирд╛ рд╕рдлрд▓ рдерд╛ред рдпрджрд┐ рд╕рдорд╕реНрдпрд╛рдПрдБ рд╣реИрдВ, рддреЛ рдореИрдВ рддреНрд░реБрдЯрд┐рдпреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реВрдБ:



 if (!generatorResults.Success) { foreach (var error in generatorResults.ParserErrors) { Console.WriteLine( "Razor error: ({0}, {1}) {2}", error.Location.LineIndex + 1, error.Location.CharacterIndex + 1, error.Message); } throw new ApplicationException(); }
      
      







рдпрджрд┐ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рд╕рдлрд▓ рд╣реЛрддрд╛ рд╣реИ, рддреЛ GeneratedCode рдкреНрд░реЙрдкрд░реНрдЯреА рдореЗрдВ DOM рдЯреНрд░реА рд╣реЛрддрд╛ рд╣реИ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЛрдб рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:



 return generatorResults.GeneratedCode;
      
      







рдЕрдм рдореБрдЭреЗ рдЯреЗрдореНрдкрд▓реЗрдЯ рд╕рдВрдХрд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:



 private static string CompileTemplate(CodeCompileUnit generatedCode) { var codeProvider = new CSharpCodeProvider(); #if DEBUG using (var writer = new StreamWriter("out.cs", false, Encoding.UTF8)) { codeProvider.GenerateCodeFromCompileUnit( generatedCode, writer, new CodeGeneratorOptions()); } #endif var outDirectory = "temp"; Directory.CreateDirectory(outDirectory); var outAssemblyName = Path.Combine(outDirectory, String.Format("{0}.dll", Guid.NewGuid().ToString("N"))); var refAssemblyNames = new List<string>(); refAssemblyNames.Add(new Uri(typeof(TemplateBase).Assembly.CodeBase).AbsolutePath); refAssemblyNames.Add("System.Core.dll"); refAssemblyNames.Add("Microsoft.CSharp.dll"); var compilerResults = codeProvider.CompileAssemblyFromDom( new CompilerParameters(refAssemblyNames.ToArray(), outAssemblyName), generatedCode); if (compilerResults.Errors.HasErrors) { var errors = compilerResults .Errors .OfType<CompilerError>() .Where(x => !x.IsWarning); foreach (var error in errors) { Console.WriteLine("Compiler error: ({0}, {1}) {2}", error.Line, error.Column, error.ErrorText); } throw new ApplicationException(); } return outAssemblyName; }
      
      







рдЙрдкрд░реЛрдХреНрдд рд╡рд┐рдзрд┐ рдореЗрдВ рдЕрд╕реЗрдВрдмрд▓реА рдХрд╛ рдирд╛рдо рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╕рдВрдХрд▓рд┐рдд рдЯреЗрдореНрдкрд▓реЗрдЯ рд╣реИред



#If DEBUG ... #endif рдореЗрдВ рд╕рдВрд▓рдЧреНрди рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдбрд┐рдмрдЧрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдЖрдкрдХреЛ рдпрд╣ рджреЗрдЦрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рдкрд░ рдХрд┐рдП рдЧрдП рд╕рднреА рдЬреЛрдбрд╝рддреЛрдбрд╝ рдХреЗ рдмрд╛рдж рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреНрдпрд╛ рдмрджрд▓ рдЧрдпрд╛ред



рдЕрдм рдореБрдЭреЗ рдмрд╕ рдЗрддрдирд╛ рдХрд░рдирд╛ рд╣реИ рдХрд┐ рд╡рд┐рдзрд╛рдирд╕рднрд╛ рдХреЛ рд▓реЛрдб рдХрд░реЗрдВ, рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреНрд▓рд╛рд╕ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВ рдФрд░ рдЗрд╕реЗ "рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░реЗрдВ":



 var assembly = Assembly.LoadFrom(outAssemblyName); var type = assembly.GetType("StandaloneRazorDemo.Template", true); var template = Activator.CreateInstance(type) as TemplateBase; using (var writer = new StringWriter()) { template.Output = writer; template.Model = GetModel(); template.Execute(); File.WriteAllText("out.txt", writer.ToString(), Encoding.UTF8); }
      
      







GetModel () рд╡рд┐рдзрд┐ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХреА рдЧрдИ рд╣реИ:



 private static OrderModel GetModel() { var model = new OrderModel { FirstName = "", LastName = "" }; model.Items = new List<OrderItemModel>(); model.Items.Add(new OrderItemModel { ProductName = "Apple", Price = 4.95m, Qty = 1 }); model.Items.Add(new OrderItemModel { ProductName = "Kiwi", Price = 9.95m, Qty = 2 }); return model; }
      
      







рдЕрдм рдлрд╝рд╛рдЗрд▓ "out.txt" рдореЗрдВ рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ "рдирд┐рд╖реНрдкрд╛рджрди" рдХрд╛ рдкрд░рд┐рдгрд╛рдо рд╣реИ:



 ,  ! #   -  - ---------- ------ ------ ------ 1 Apple 4,95 1 4,95 2 Kiwi 9,95 2 19,90 : 24,85 WBR, ACME team
      
      







рд╡рд╣ рд╕рдм рд╣реИ!



рдЙрджрд╛рд╣рд░рдг рдХреЛрдб:

StandaloneRazorDemo.zip



All Articles