ASP.NET MVC使用RazorEngine解析模板生成静态页_实用技巧

简述

      Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项。在早期的MVC版本中默认使用的是ASPX模板引擎,Razor在语法上的确不错,用起来非常方便,简洁的语法与.NET Framework 结合,广泛应用于ASP.NET MVC 项目。

      我们在很多项目开发中会常常用到页面静态化,页面静态化有许多方式,最常见的就是类似很多PHP CMS种使用的 标签替换的方式(如:帝国CMS、EcShop等),还有很多都是伪静态,伪静态我们就不做过多解释,通过路由或Url重写来实现就可以了。Razor为我们提供了更加方便的模板解析方式,任何东西都是两方面的,技术也是如此,Razor解析模板虽然更加方便、简洁,但是对于模板制作人员来说也是有一定的技术要求,或者对于开发一套模板制作功能来说,考虑的要更多一些。我们不再去探究这些问题,我们更注重哪种技术更容易、更方便、更好的满足我们项目的需求。

如何使用RazorEngine

       今天来简单介绍一下如何使用RazorEngine解析模板生成静态页面,RazorEngine它是基于微软的Razor之上,包装而成的一个可以独立使用的模板引擎。也就是说,保留了Razor的模板功能,但是使得Razor脱离于Asp.net MVC,能够在其它应用环境下使用,项目地址:https://github.com/Antaris/RazorEngine

首先我们去codeplex上下两个需要的dll http://razorengine.codeplex.com

      看到网上很多介绍RazorEngine的基础用法的,讲解的都比较详细,对于RazorEngine运行原理很清晰,我们在这里就不重复介绍了。写这篇文章是对于很多新手同学来说比较喜欢“拿来主义”,基本的用法原理都能看懂,但是如何应用到项目中还是有些不是很清晰,我们只讲讲如何在项目中运用。

本文分为两部分:第一个部分,基本的单数据模型模板解析;第二部分,面向接口的多数据模型模板解析

第一个部分 基本的单数据模型模板解析

一、我们创建一个MVC项目,并且添加上面的两个DLL引用,然后我们新建一个简单的文章类

public class Articles
 {
 /// <summary>
 /// 文章ID
 /// </summary>
 public int Id { get; set; }
 /// <summary>
 /// 文章标题
 /// </summary>
 public string Title { get; set; }
 /// <summary>
 /// 文章内容
 /// </summary>
 public string Content { get; set; }
 /// <summary>
 /// 作者
 /// </summary>
 public string Author { get; set; }
 /// <summary>
 /// 发布时间
 /// </summary>
 public DateTime CreateDate { get; set; }
 }

二、我们新建一个Razor的Html模板

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title>@Model.Title</title>
</head>
<body>
 <h1>@Model.Title</h1>
 <p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>
 <p>@Raw(Model.Content)</p>
</body>
</html>

说明:Model就是我们的文章实体类  在MVC的试图页cshtml中 我们一般都是在控制器里传递这个实体类 然后在视图页中 @model Models.Articles 来接收这个实体类 然后通过“@Model.”来输出内容,在Razor模板中是一样的,只是不用@model Models.Articles 来接收了,其它的语法跟在.cshtml试图页中是一样的,这么说多余了,因为写法不一样他就不是Razor了

三、我们写一个方法来获取模板页的Html代码

 /// <summary>
 /// 获取页面的Html代码
 /// </summary>
 /// <param name="url">模板页面路径</param>
 /// <param name="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>
 /// 获取页面的编码
 /// </summary>
 /// <param name="html">Html源码</param>
 /// <returns></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; }
 }

四、我们写一个方法 用于生成Html静态页

/// <summary>
 /// 创建静态文件
 /// </summary>
 /// <param name="result">Html代码</param>
 /// <param name="createpath">生成路径</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));//去除UTF-8 BOM
   sw.Write(result);
   sw.Close();
   fs2.Close();
   fs2.Dispose();
   return true;
  }
  catch { return false; }
  }
  return false;
 }

五、我们来写个方法调用静态模板,并且传递数据模型实体类 创建Html静态页

/// <summary>
 /// 解析模板生成静态页
 /// </summary>
 /// <param name="temppath">模板地址</param>
 /// <param name="path">静态页地址</param>
 /// <param name="t">数据模型</param>
 /// <returns></returns>
 public bool CreateStaticPage(string temppath, string path, RazorEngineTemplates.Models.Articles t)
 {
  try
  {
  //获取模板Html
  string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);

  //初始化结果
  string result = string.Empty;

  //解析模板生成静态页Html代码
  result = Razor.Parse(TemplateContent, t);

  //创建静态文件
  return CreateFileHtmlByTemp(result, path);
  }
  catch (Exception e)
  {
  throw e;
  }
 }

好了,大功告成,是不是很简单。

这里只是一个很简单的应用,没有读取数据,也没有列表,只有一个文章数据模型,下一部分我们将介绍 多模型模板解析,因为是多模型 所以 生成静态页面的时候 就不是传递一个具体模型实体类 我们会用到 反射,通过反射模型属性 获取数据,有不熟悉反射的可以提前研究一下,也可以直接看下一部分的反射代码也很简单的。

第二部分 面向接口的多数据模型模板解析

这一部分,我们介绍使用接口来解析模板,包括列表等多种模型解析,用到了Spring注入和反射还有接口等,有不熟悉的可以百度搜一下或者评论留言。

我们接着上面的示例,我们新建两个类库 一个是存放数据模型的 我们叫Domain;另外一个是接口和实现类的 我们叫Service,然后我们添加他们之间的引用

一、我们在Domain下创建几个测试类

Articles - 文章测试类

Company - 公司测试类

Column - 栏目测试类

TemplateView - 模型解析类(这个是不是比较弱智?我也没深入研究多个模型怎么反射出来 所以 我加了这么个算是公用的类 没有对应的数据表 只是解析模板的时候 作为中间件用用)

public class Articles
 {
 /// <summary>
 /// 文章ID
 /// </summary>
 public int Id { get; set; }
 /// <summary>
 /// 文章标题
 /// </summary>
 public string Title { get; set; }
 /// <summary>
 /// 文章内容
 /// </summary>
 public string Content { get; set; }
 /// <summary>
 /// 作者
 /// </summary>
 public string Author { get; set; }
 /// <summary>
 /// 发布时间
 /// </summary>
 public DateTime CreateDate { get; set; }
 }
  public class Company
 {
 /// <summary>
 /// 公司Id
 /// </summary>
 public int Id { get; set; }
 /// <summary>
 /// 公司名称
 /// </summary>
 public string CompanyName { get; set; }
 /// <summary>
 /// 公司电话
 /// </summary>
 public string CompanyTel { get; set; }
 /// <summary>
 /// 联系人
 /// </summary>
 public string ContectUser { get; set; }
 /// <summary>
 /// 创建时间
 /// </summary>
 public DateTime CreateDate { get; set; }
 }
   public class Column
 {
 /// <summary>
 /// 栏目ID
 /// </summary>
 public int Id { get; set; }
 /// <summary>
 /// 栏目名称
 /// </summary>
 public string Title { get; set; }
 /// <summary>
 /// 文章列表
 /// </summary>

 public virtual ICollection<Articles> Articles { get; set; }
 }
   public class TemplateView
 {
 /// <summary>
 /// ID
 /// </summary>
 public int Id { get; set; }
 /// <summary>
 /// 标题
 /// </summary>
 public string Title { get; set; }
 /// <summary>
 /// 内容
 /// </summary>
 public string Content { get; set; }
 /// <summary>
 /// 作者
 /// </summary>
 public string Author { get; set; }
 /// <summary>
 /// 时间
 /// </summary>
 public DateTime CreateDate { get; set; }
 /// <summary>
 /// 公司名称
 /// </summary>
 public string CompanyName { get; set; }
 /// <summary>
 /// 公司电话
 /// </summary>
 public string CompanyTel { get; set; }
 /// <summary>
 /// 联系人
 /// </summary>
 public string ContectUser { get; set; }
 /// <summary>
 /// 文章列表
 /// </summary>
 public virtual ICollection<Articles> Articles { get; set; }
 }

二、我们在Service下创建一个基础操作接口以及其实现类(里面的很多方法 比如:获取页面的Html代码、获取页面的编码以及创建静态文件等 是没有必要写在接口的 这个可以写到公用的类库里,因为这里就用到这么几个方法 所以我没有加公用类库 就直接写在这里面了)

/// <summary>
 /// 基础操作接口
 /// </summary>
 /// <typeparam name="T"></typeparam>
 public interface IRepository<T> where T : class
 {
 /// <summary>
 /// 解析模板生成静态页
 /// </summary>
 /// <param name="temppath">模板地址</param>
 /// <param name="path">静态页地址</param>
 /// <param name="t">数据模型</param>
 /// <returns></returns>
 bool CreateStaticPage(string temppath, string path, T t); 

 /// <summary>
 /// 获取页面的Html代码
 /// </summary>
 /// <param name="url">模板页面路径</param>
 /// <param name="encoding">页面编码</param>
 /// <returns></returns>
 string GetHtml(string url, System.Text.Encoding encoding);

 /// <summary>
 /// 获取页面的编码
 /// </summary>
 /// <param name="html">Html源码</param>
 /// <returns></returns>
 System.Text.Encoding GetEncoding(string html);

 /// <summary>
 /// 创建静态文件
 /// </summary>
 /// <param name="result">Html代码</param>
 /// <param name="createpath">生成路径</param>
 /// <returns></returns>
 bool CreateFileHtmlByTemp(string result, string createpath);
 }
/// <summary>
 /// 基础接口实现类
 /// </summary>
 /// <typeparam name="T"></typeparam>
 public abstract class RepositoryBase<T> : IRepository<T> where T : class
 {
 /// <summary>
 /// 解析模板生成静态页
 /// </summary>
 /// <param name="temppath">模板地址</param>
 /// <param name="path">静态页地址</param>
 /// <param name="t">数据模型</param>
 /// <returns></returns>
 public bool CreateStaticPage(string temppath, string path, T t)
 {
  try
  {
  //实例化模型
  var Entity = new Domain.TemplateView();

  //获取模板Html
  string TemplateContent = GetHtml(temppath, System.Text.Encoding.UTF8);
  //初始化结果
  string result = "";

  //反射赋值
  Type typeT = t.GetType();
  Type typeEn = Entity.GetType();

  System.Reflection.PropertyInfo[] propertyinfosT = typeT.GetProperties();

  foreach (System.Reflection.PropertyInfo propertyinfoT in propertyinfosT)
  {
   System.Reflection.PropertyInfo propertyinfoEn = typeEn.GetProperty(propertyinfoT.Name);
   if (propertyinfoEn != null && propertyinfoT.GetValue(t, null) != null)
   {
   propertyinfoEn.SetValue(Entity, propertyinfoT.GetValue(t, null), null);
   }
  }

  //很多时候 我们并没有创建复杂的主外键关系 例如栏目下的文章 我们仅仅是在文章表中添加了一个所属栏目ID的字段
  //并没有创建关联 这种情况下 我们直接获取栏目的时候 是获取不到文章列表的
  //包括很多自定义的模型和字段 比如 文章的内容 可能不跟文章一个表 而是一个单独的大数据字段表 这种情况下 我们的
  //TemplateView.Content就需要单独获取一下另一个数据模型里的 这个文章的内容 这种时候 我们可以在这里重新给他赋值

  //如 传入的模型是 文章
  //if(t is Domain.Articles)
  //{
  // Entity.Content= 查询大数据字段表中这篇文章的内容;

  //}

  result = Razor.Parse(TemplateContent, Entity);

  return CreateFileHtmlByTemp(result, path);
  }
  catch (Exception e)
  {
  throw e;
  }
 }

 /// <summary>
 /// 获取页面的Html代码
 /// </summary>
 /// <param name="url">模板页面路径</param>
 /// <param name="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>
 /// 获取页面的编码
 /// </summary>
 /// <param name="html">Html源码</param>
 /// <returns></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>
 /// 创建静态文件
 /// </summary>
 /// <param name="result">Html代码</param>
 /// <param name="createpath">生成路径</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));//去除UTF-8 BOM
   sw.Write(result);
   sw.Close();
   fs2.Close();
   fs2.Dispose();
   return true;
  }
  catch { return false; }
  }
  return false;
 }
 }

三、我们分别创建 文章管理、公司管理、栏目管理的接口和实现类 并且他们都集成基础操作

   /// <summary>
 /// 文章管理
 /// </summary>
   public interface IArticleManage:IRepository<Domain.Articles>
 {
 }
 public class ArticleManage:RepositoryBase<Domain.Articles>,IArticleManage
 {
 }

  /// <summary>
 /// 公司管理
 /// </summary>
 public interface ICompanyManage:IRepository<Domain.Company>
 {
 }
  public class CompanyManage:RepositoryBase<Domain.Company>,ICompanyManage
 {
 }

  //栏目管理
 public interface IColumnManage:IRepository<Domain.Column>
 {
 }
  public class ColumnManage:RepositoryBase<Domain.Column>,IColumnManage
 {
 }

四、注入Xml

<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
 <description>Spring注入Service,容器指向本层层封装的接口</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>

五、我们分别初始化一个文章类、一个公司类(没有管理数据表,它下面没有文章列表 栏目模型我就不初始化了,怎么输出列表 大家可以参考下 栏目模板)

public class HomeController : Controller
 {
 /// <summary>
 /// 声明一下注入接口
 /// </summary>
 public IArticleManage 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()
 {
  //初始化一个文章数据模型
  var entityArticle = new Domain.Articles() { Id = 1, Title = "这里是文章标题", Content = "<span style=\"color:red;\">这里是文章内容</span>", Author = "张三", CreateDate = DateTime.Now };

  //初始化一个公司数据模型
  var entityCompany = new Domain.Company() { Id = 1, CompanyName = "这里是公司名称", CompanyTel = "公司电话", ContectUser = "张三", CreateDate = DateTime.Now };

  //调用方法生成静态页面
  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 Contact()
 {
  ViewBag.Message = "Your contact page.";

  return View();
 }

 }

六、这是测试的简单的文章模板、公司模板和栏目模板

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>@Model.Title</title>
</head>
<body>
 <h1>@Model.Title</h1>
 <p>作者:@Model.Author - 发布时间:@Model.CreateDate</p>
 <p>@Raw(Model.Content)</p>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title></title>
</head>
<body>
 <p>公司名称:@Model.CompanyName</p>
 <p>公司电话:@Model.CompanyTel</p>
 <p>联系人:@Model.ContectUser</p>
 <p>创建时间:@Model.CreateDate</p>
</body>
</html>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
 <title></title>
</head>
<body>
 <p>栏目标题: @Model.Title</p>
 <p>
 文章列表
 <ul>
  @foreach(var item in @Model.Articles)
  {
  <li>
  <a href="">
   <span>@item.Title</span>
   <span>@item.Author</span>
   <span>@item.CreateDate</span>
  </a>
  </li>
  }
 </ul>
 </p>
</body>
</html>

我们运行一下,大功告成~~~

        

怎么排序?怎么获取前几条?怎么格式化日期时间?怎么分页?

这可是Razor啊,这都不需要再多讲了吧,简单一说,如果你传入数据前没有事先排序或者获取前几条,这些操作要做模板里操作 那跟在.cshtml里基本是一样的

@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>
}

应用还是很广泛的,而且解析代码相对于标签替换来说十分简洁、高效。有时间可以多研究研究,改天有空写一个模板替换标签的供大家参考一下。

还是那句老话,这篇文章仅仅是个人的一些理解和实现,可能中间会出现一些不合理的地方或是错误,请大家指正,我们共同学习研究。
以上就是本文的全部内容,希望大家喜欢。
原文地址:http://yuangang.cnblogs.com

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索asp.net
, mvc
, 静态页
解析模板
,以便于您获取更多的相关知识。

时间: 2024-12-03 16:52:49

ASP.NET MVC使用RazorEngine解析模板生成静态页_实用技巧的相关文章

asp.net mvc实现简单的实时消息推送_实用技巧

因为项目需要,需要在网页上实现消息的推送.在百度上搜索了一下,发现实现网页上的消息推送,可以使用asp.net 中的SignalR类库,当然也可以使用H5的WebSocket  Ajax的轮回.当然此处我们使用asp.net 中的SignalR类库.因为它可以实现网页上消息的实时推送.什么是实时推送呢,我简单的说一下我个人的理解吧.实时:在同一时间类发生的事情,当然在计算机中并不是绝对的实时,因为CPU在同一时间片只能处理一个任务,那么这个时候疑问又来了? 我们平时使用电脑又上网,又听音乐是如何

ASP.NET MVC使用Ajax的辅助的解决方法_实用技巧

前言:前面我们已经简单的介绍过了MVC如何Jquery,因为我们如果使用Ajax的话必须要了解Jquery,这篇博客我们将大致了解一下ASP.NET MVC如何使用Ajax的辅助方法,此博客是我的读书笔记,如果那里写的不好,还请各位朋友提出来,我们共同学习.1.准备工作 (1)在MVC刚开始学习的时候,我们就需要介绍ASP.NET MVC框架中的HTML的辅助方法,但是这类文章现在已经很多了,而且个人感觉很简单,所以没有写笔记,我在这里就不介绍了. (2)ASP.NET MVC框架中的HTML辅

ASP.NET MVC小结之基础篇(二)_实用技巧

整理除了这个笔记,共享一下子,基本MVC的所有东西都介绍了,但是都是很基础的东西.本来打算一篇发表完的,但是发现东西有点多,所以分成了两篇文章,这是最后一篇了! 1.ASP.NET MVC请求过程 1 2.Controller (1) 控制器在ASP.NET MVC中扮演着处理客户端请求的角色 1)必须实现System.Web.Mvc.IController接口 ->通常直接继承System.Web.MVC.Controller类 2)必须要以Controller结尾 3)通过不同的Action

ASP.NET MVC中将控制器分离到类库的实现_实用技巧

前言 在.ASP.NET MVC的开发中,我们创建完项目之后,ASP.NET MVC是已Model-Controller-View的形式存在的,在创建项目自动生成的内容上Model我们很容易分离成类库,所以这里不予说明,那么这时候我们就像Controller是不是也能够分离出去呢?答案是肯定的,下面我们探讨一下Controller如何分离出去. 这里我提供两种分离的方法,一是重写方法继承自IControllerFactory接口,实现里面的方法,二是MVC提供了直接在路由注册里面去控制控制器的书

ASP.NET MVC小结之基础篇(一)_实用技巧

前言:前几天要准备一个演讲,所以准备了MVC的一些基本的东西,以前也使用过MVC,但是只是使用,而不是去了解,所以趁着这个机会好好的把别人的MVC视频看了一下(是一个微软的MVP会员发布的视频,相信有些人都看过),整理除了这个笔记,共享一下子,基本MVC的所有东西都介绍了,但是都是很基础的东西.本来打算一篇发表完的,但是发现东西有点多,所以分成了两篇文章! 什么是ASP.NET MVC (1) ASP.NET MVC是微软官方提供的MVC模式编写ASP.NET Web应用程序的一个框架 (2)M

用Fine Uploader+ASP.NET MVC实现ajax文件上传[代码示例]_实用技巧

This project attempts to achieve a user-friendly file-uploading experience over the web. It's built as a Javascript plugin for developers looking to incorporate file-uploading into their website. Fine Uploader 不依赖于 jQuery,也就是说不引用jquery.js,也可以正常使用.同时,

ASP.NET MVC中图表控件的使用方法_实用技巧

微软发布了一个强大的ASP.NET的图表控件,支持丰富的图表选项设置-包括列,点,泡沫,饼图,圆环图,金字塔,漏斗,盒形图,面积,范围,AJAX的互动,以及更多.Microsoft图表控件示例项目包括ASP.NET页的图表样本超过200个.在这篇文章中,我将展示如何在ASP.NET MVC中使用图表控件. 这里介绍一个非常简单的项目,显示了一个类的结果比较.两个字段 - ID(这是唯一的一个学生)和GPA(平均成绩) - 代表一个特定的学生的结果.各种图表结果显示,学生的结果进行比较.我希望把重

ASP.NET MVC:Filter和Action的执行介绍_实用技巧

根据controller的名字正确的实例化了一个controller对象.回到MVCHandler的BeginProcessRequest方法,可以看到,当得到controller对象之后,首先判断它是不是IAsyncController,如果是则会创建委托用来异步执行.通常情况下,我们都是继承自Controller类,这不是一个IAsyncController,于是会直接执行Controller的Execute方法.Execute方法是在Controller的基类ControllerBase中

Asp.net MVC中获取控制器的名称的方法_实用技巧

1.视图中 string controller = ViewContext.RouteData.Route.GetRouteData(this.Context).Values["controller"].ToString(); string controller = ViewContext.RouteData.Values["controller"].ToString(); 2.控制器的action中 string controller = RouteData.Ro