asp.net mvc uses razorengine parsing templates to generate static pages _ Practical Tips

Source: Internet
Author: User
Tags datetime field table reflection in domain

Briefly

Razor is the new technology added to ASP.net MVC 3 as a new alternative to the ASPX engine. The ASPX template engine was used by default in earlier versions of MVC, and razor is really good in syntax, easy to use, and a concise syntax that combines with the. NET Framework and is widely used in asp.net MVC projects.

We often use page statics in many project development, there are many ways to page static, the most common is similar to many PHP CMS to use the way tag replacement (such as: Imperial CMS, Ecshop, etc.), there are many are pseudo static, pseudo static we do not do too much explanation, It can be done by routing or URL rewriting. Razor provides us with a more convenient way to parse the template, everything is two, technology is the same, Razor parsing template Although more convenient, concise, but for the template production staff is also a certain technical requirements, or for the development of a set of template production functions, consider more. We no longer explore these issues, we pay more attention to which technology is easier, more convenient and better to meet the needs of our projects.

How to use Razorengine

Today to briefly explain how to use the Razorengine parsing template to generate static pages, razorengine it is based on the Microsoft Razor, packaged as a stand-alone template engine can be used. That is, it retains the razor template functionality, but makes razor out of ASP.net MVC and can be used in other applications, project address: Https://github.com/Antaris/RazorEngine

First we go to CodePlex up and down two required DLLs http://razorengine.codeplex.com

See a lot of online introduction razorengine of the basic usage, the explanation is more detailed, for the razorengine operation principle is very clear, we here will not repeat the introduction. Writing this article is for many novice students like "copycat", the basic principle of usage can understand, but how to apply to the project or some is not very clear, we only talk about how to use in the project.

This paper is divided into two parts: the first part, the basic single data Model template parsing; the second part, interface-oriented model template parsing

The first part of the basic single Data Model template parsing

First, we create an MVC project and add the two DLL references above, and then we build a new simple article class

public class articles
 {
 ///<summary>
 ///article ID
 ///</summary> public
 int ID {get; set;}
 ///<summary>
 ///article title
 ///</summary> public
 string Title {get; set;}
 <summary>
 ///article content
 ///</summary> public
 string content {get; set;}
 <summary>
 ///author
 ///</summary> public
 string Author {get; set;}
 <summary>
 ///release time
 ///</summary> public
 DateTime createdate {get; set;}
 }

Second, we create a new razor HTML template

<! DOCTYPE html>
 
 

Description: Model is our article entity class in the MVC attempt page cshtml we typically pass the entity class in the controller and then @model models.articles in the View page to receive the entity class and then pass "@Model." To output the content, in the Razor template is the same, just do not need @model models.articles to receive, the other syntax follows. cshtml try to page is the same, so needless to say, because the writing is not the same he is not razor

Third, we write a method to get the HTML code of the template page

 <summary>///get the HTML code for the page///</summary>///<param name= "url" > template page path </param>///<pa Ram name= "encoding" > page encoding </param>///<returns></returns> public string gethtml (string URL, System . Text.encoding Encoding) {byte[] buf = new WebClient ().
  Downloaddata (URL); if (encoding!= null) return encoding.
  GetString (BUF);
  String html = System.Text.Encoding.UTF8.GetString (BUF);
  encoding = getencoding (HTML);
  if (encoding = NULL | | | encoding = = SYSTEM.TEXT.ENCODING.UTF8) return HTML; return encoding.
 GetString (BUF); ///<summary>///Get the encoding of the page///</summary>///<param name= "html" >html source code </param>///<ret Urns></returns> Public System.Text.Encoding getencoding (string html) {string pattern = @ ' (? i) \bcharset= (?
  ; charset>[-a-za-z_0-9]+) "; String charset = Regex.match (HTML, pattern). Groups["CharSet"].
  Value;
  try {return System.Text.Encoding.GetEncoding (charset);} catch (argumentexception) {return null;}

 }

Four, we write a method to generate an HTML static page

<summary>///Create a static file///</summary>///<param name= "result" >html code </param>///<param Name= "Createpath" > Build path </param>///<returns></returns> public bool Createfilehtmlbytemp (string result, string createpath) {if (!string). IsNullOrEmpty (Result)) {if (string).
  IsNullOrEmpty (Createpath)) {Createpath = "/default.html"; string filepath = Createpath. Substring (Createpath.
  LastIndexOf (@ "\")); Createpath = Createpath. Substring (0, Createpath.
  LastIndexOf (@ "\")); if (!
  Directory.Exists (Createpath)) {directory.createdirectory (Createpath);
  } Createpath = Createpath + filepath;
   try {FileStream FS2 = new FileStream (Createpath, FileMode.Create); StreamWriter sw = new StreamWriter (FS2, New System.Text.UTF8Encoding (false));//Remove UTF-8 BOM SW.
   Write (result); Sw.
   Close (); FS2.
   Close (); FS2.
   Dispose ();
  return true;
  catch {return false;}
 return false;
 }

Let's write a method to invoke the static template and pass the data model entity class to create an HTML static page

<summary>
 ///parsing templates generate static pages
 ///</summary>
 ///<param name= "TempPath" > Template address </param >
 ///<param name= "path" > static page address </param>
 ///<param name= "T" > Data Model </param>
 /// <returns></returns> Public
 bool Createstaticpage (string TempPath, String path, RazorEngineTemplates.Models.Articles t)
 {
  try
  {
  //Get template html
  string templatecontent = Gethtml (TempPath, System.Text.Encoding.UTF8);

  Initialize result
  String results = string. Empty;

  Parse template generates static page HTML code result
  = Razor.parse (TemplateContent, t);

  Create a static file return
  createfilehtmlbytemp (result, path);
  }
  catch (Exception e)
  {
  throw e;
  }
 }

Well, it's not easy.

This is just a very simple application, there is no reading data, there is no list, there is only one article data model, the next part we will introduce the multiple model template parsing, because it is multiple models, so when generating static pages, it is not passing a concrete model entity class. We use reflection to get data through reflection model properties, It is also easy to look at the reflection code of the next part if you are unfamiliar with reflection.

The second part of interface-oriented majority model template parsing

This part, we introduce the use of interfaces to parse templates, including lists, and many other model analysis, using spring injection and reflection and interface, there are unfamiliar can Baidu search or comment comments.

We go on to the example above, we create two class libraries one is the data model we call domain; the other is the interface and implementation class we call the service, and then we add the references between them

First, we create several test classes in domain

Articles-Article Test class

Company-Testing class

Column-Column Test class

Templateview-Model parsing class (Is this more retarded?) I didn't delve into how multiple models were reflected, so I added a common class. No corresponding datasheet is used as a middleware when parsing a template.

public class Articles {///<summary>///article ID///</summary> public int id {get; set;}
 <summary>///article title///</summary> public string Title {get; set;}
 <summary>///article content///</summary> public string content {get; set;}
 <summary>///author///</summary> public string Author {get; set;}
 <summary>///release Time///</summary> public DateTime createdate {get; set;}
 public class Company {///<summary>///corporate ID///</summary> public int Id {get; set;}
 <summary>///Company Name///</summary> public string CompanyName {get; set;}
 <summary>///Company Tel///</summary> public string Companytel {get; set;}
 <summary>///Contact///</summary> public string Contectuser {get; set;}
 <summary>///creation time///</summary> public DateTime createdate {get; set;} } public class Column {///<summary&Gt
 Column ID///</summary> public int Id {get; set;}
 <summary>///Column name///</summary> public string Title {get; set;}
 <summary>///Articles List///</summary> public virtual icollection<articles> articles {get; set;}
 public class Templateview {///<summary>///ID///</summary> public int id {get; set;}
 <summary>///title///</summary> public string Title {get; set;}
 <summary>///Content///</summary> public string content {get; set;}
 <summary>///author///</summary> public string Author {get; set;} 
 <summary>///time///</summary> public DateTime createdate {get; set;}
 <summary>///Company Name///</summary> public string CompanyName {get; set;}
 <summary>///Company Tel///</summary> public string Companytel {get; set;} <summary>///Contact///</summary> public string CoNtectuser {get; set;}
 <summary>///Articles List///</summary> public virtual icollection<articles> articles {get; set;}

 }

Second, we create a basic operating interface under the service and its implementation class (many of the methods inside such as: Get the page's HTML code, get the page encoding and create a static file, etc.) is not necessary to write in the interface of this can be written to the common library, Because there are so many ways to use it, so I don't have to add a common class library to write directly in this area.

<summary>///Basic Operation interface///</summary>///<typeparam name= "T" ></typeparam> public interface irepository<t> where T:class {///<summary>///resolution templates generate static pages///</summary>///<param name= "Te Mppath "> Template address </param>///<param name=" path "> static page address </param>///<param name=" T "> Data Model </ 

 param>///<returns></returns> bool Createstaticpage (string TempPath, string path, T t); <summary>///get the HTML code for the page///</summary>///<param name= "url" > template page path </param>///<para M name= "encoding" > page encoding </param>///<returns></returns> string gethtml (string URL,

 System.Text.Encoding Encoding); <summary>///Get the page encoding///</summary>///<param name= "html" >html source code </param>///<returns

 ></returns> System.Text.Encoding getencoding (string html); <summary>///Create a static file///</summary>///<param name= "reSult ">html code </param>///<param name=" Createpath "> Build path </param>///<returns></returns
 > bool Createfilehtmlbytemp (string result, string createpath); ///<summary>///Basic Interface Implementation Class///</summary>///<typeparam name= "T" ></typeparam> public Abstrac T class repositorybase<t>: irepository<t> where T:class {///<summary>///parse template generate static page///</su mmary>///<param name= "TempPath" > Template address </param>///<param name= "path" > static page address </param>/// ;p Aram Name= "T" > Data Model </param>///<returns></returns> public bool Createstaticpage (string

  TempPath, string path, T t) {try {//instantiate model var Entity = new Domain.templateview ();
  Gets the template html string templatecontent = gethtml (TempPath, System.Text.Encoding.UTF8);

  Initialize results string result = "";
  Reflection Assignment Type Typet = T.gettype ();

  Type Typeen = Entity.gettype (); system.reflection.propertyinfo[] Propertyinfost = tYpet.getproperties (); foreach (System.Reflection.PropertyInfo propertyinfot in propertyinfost) {System.Reflection.PropertyInfo Propertyinf
   Oen = Typeen.getproperty (propertyinfot.name); if (Propertyinfoen!= null && propertyinfot.getvalue (t, NULL)!= null) {Propertyinfoen.setvalue (Entity, pro
   Pertyinfot.getvalue (t, NULL), NULL); Many times we didn't create complex primary foreign key relationships such as articles under columns we just added a column ID to the article table the field//does not create an association in this case we get the column directly when we are not getting the list of articles//including many custom models and  Fields such as the content of the article may not be a table with the article but a single large data field table in this case our//templateview.content need to take a separate look at the content of this article in another data model. We can give him a new assignment here.
   
  The incoming model is the content of this article in the//if (T is domain.articles)//{//entity.content= Query large data field table;

  result = Razor.parse (TemplateContent, Entity);
  return createfilehtmlbytemp (result, path);
  catch (Exception e) {throw e; }///<summary>///gets the HTML code for the page///</summary>///<param name= "url" > template page path </param>///& Lt;param name= "Encoding" > page encoding </param>///<returns></returns> public string gethtml (string url, System.Text.Encoding Encoding) {byte[] bu f = new WebClient ().
  Downloaddata (URL); if (encoding!= null) return encoding.
  GetString (BUF);
  String html = System.Text.Encoding.UTF8.GetString (BUF);
  encoding = getencoding (HTML);
  if (encoding = NULL | | | encoding = = SYSTEM.TEXT.ENCODING.UTF8) return HTML; return encoding.
 GetString (BUF); ///<summary>///Get the encoding of the page///</summary>///<param name= "html" >html source code </param>///<ret Urns></returns> Public System.Text.Encoding getencoding (string html) {string pattern = @ ' (? i) \bcharset= (?
  ; charset>[-a-za-z_0-9]+) "; String charset = Regex.match (HTML, pattern). Groups["CharSet"].
  Value;
  try {return System.Text.Encoding.GetEncoding (charset);}
 catch (ArgumentException) {return null;} ///<summary>///Create a static file///</summary>///<param name= "result" >html code </param>///&LT;PA Ram NamE= "Createpath" > Build path </param>///<returns></returns> public bool Createfilehtmlbytemp (string result, string createpath) {if (!string). IsNullOrEmpty (Result)) {if (string).
  IsNullOrEmpty (Createpath)) {Createpath = "/default.html"; string filepath = Createpath. Substring (Createpath.
  LastIndexOf (@ "\")); Createpath = Createpath. Substring (0, Createpath.
  LastIndexOf (@ "\")); if (!
  Directory.Exists (Createpath)) {directory.createdirectory (Createpath);
  } Createpath = Createpath + filepath;
   try {FileStream FS2 = new FileStream (Createpath, FileMode.Create); StreamWriter sw = new StreamWriter (FS2, New System.Text.UTF8Encoding (false));//Remove UTF-8 BOM SW.
   Write (result); Sw.
   Close (); FS2.
   Close (); FS2.
   Dispose ();
  return true;
  catch {return false;}
 return false;

 }
 }

Third, we create article management, corporate Management, column management interface and implementation classes and they all integrate the basic operations

<summary>
 ///article management
 ///</summary> public
 Interface iarticlemanage:irepository< Domain.articles>
 {
 } public
 class Articlemanage:repositorybase<domain.articles>, Iarticlemanage
 {
 }

///<summary>
 ///Corporate Administration
 ///</summary> Public
 interface Icompanymanage:irepository<domain.company>
 {
 } public
class Companymanage:repositorybase <domain.company>,icompanymanage
 {
 }

//Column Management public
 interface Icolumnmanage:irepository <Domain.Column>
 {
 } public
class Columnmanage:repositorybase<domain.column>, Icolumnmanage
 {
 }

Iv. Injection of XML

<?xml version= "1.0" encoding= "Utf-8"?> <objects xmlns=
"Http://www.springframework.net" >
 < Description>spring inject Service, the container points to the interface encapsulated in the layer </description>
 <object id= "Service.articlemanage" type= " Service.articlemanage,service "singleton=" false ">
 </object>
 <object id=" Service.columnmanage "Type=" Service.columnmanage,service "singleton=" false ">
 </object>
 <object id=" Service.companymanage "type=" Service.companymanage,service "singleton=" false ">
 </object>
</ Objects>

Five, we initialize an article class, a company class (No management data table, it does not have a list of articles below the column model I will not initialize, how output list you can refer to the column template)

public class Homecontroller:controller {///<summary>///declare injection interface///</summary> public Iarticlemana GE articlemanage = Spring.Context.Support.ContextRegistry.GetContext ().
 GetObject ("Service.articlemanage") as Iarticlemanage; Public Icompanymanage companymanage = Spring.Context.Support.ContextRegistry.GetContext ().
 GetObject ("Service.companymanage") as Icompanymanage; Public Icolumnmanage columnmanage = Spring.Context.Support.ContextRegistry.GetContext ().


 GetObject ("Service.columnmanage") as Icolumnmanage; Public ActionResult Index () {//Initialize an article data model var entityarticle = new Domain.articles () {Id = 1, title = "Here is Article title", Co

  ntent = "<span style=\" color:red;\ "> here is the article content </span>", Author = "John", CreateDate = DateTime.Now}; Initialize a company data model var entitycompany = new Domain.company () {Id = 1, CompanyName = "Here is company name", Companytel = "Company Phone", Contectus

  ER = "John", CreateDate = DateTime.Now}; Invoke method to generate static page Articlemanage.createstaticpage (Server.MapPath ("/teMplates/temp_article.html "), Server.MapPath ("/pages/news/"+ DateTime.Now.ToString (" YYYYMMDDHHMMSS ") +" 1.html "),
  Entityarticle); Companymanage.createstaticpage (Server.MapPath ("/templates/temp_company.html"), Server.MapPath ("/Pages/news/" +

  DateTime.Now.ToString ("YYYYMMDDHHMMSS") + "2.html"), Entitycompany);
 return View ();

  Public ActionResult About () {viewbag.message = "Your Application description page.";
 return View ();

  Public ActionResult Contacts () {viewbag.message = "Your Contact page."
 return View ();

 }
 
 }

Six, this is the test of simple article templates, company templates and column templates

<! DOCTYPE html>
 
 
<! DOCTYPE html>
 
 
<! DOCTYPE html>
 
 

Let's run it.

How to sort? How do I get the first few? How do I format the date time? How to pagination?

This is razor ah, this does not need to say more, simply, if you pass the data before the sorting or get the first few, these operations to do in the template operation that is the same as in the. Cshtml is basically the same.

@foreach (var item in @Model. listcolumn)
{

 <div >
@if (@item. Linkurl==null)
 {
 <ul>
@foreach (Var article in @item. Com_article.take (15). OrderByDescending (p=>p.updatedate))
{

<li>
  <a href= "@article. Linkurl "class=" gd-a ">
  <div> @article. title</div></a>
  </li>
}
 </ul>
 }
 else
 {

 }
</ Div>
}

Application is still very extensive, and parsing code is very concise and efficient relative to label substitution. Have time to study more, another day to write a template to replace the label for your reference.

Or the old saying, this article is only a personal understanding and realization, may appear in the middle of some unreasonable place or mistake, please correct me, we study together.
The above is the entire content of this article, I hope you like.
Original address: http://yuangang.cnblogs.com

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.