二、博客系统后台布局实现

2.1.这里所用的是MVC的布局页来实现的,后台主要分为三部分:导航、菜单、主要内容

代码实现:

这里把后台单独放在一个区域里面,所以我这里建立一个admin的区域

在布局页_Layout.cshtml引入公共的一些css文件以及js文件(ZUI:http://zui.sexy/。metisMenu:http://mm.onokumus.com/

布局页代码_Layout.cshtml:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6. <title>@ViewBag.Title - 博客系统后台管理</title>
  7. <link href="~/Content/lib/zui/css/zui.css" rel="stylesheet" />
  8. <link href="~/Content/lib/zui/css/zui-theme.css" rel="stylesheet" />
  9. <link href="~/Content/lib/font-awesome/css/font-awesome.css" rel="stylesheet" />
  10. <link href="~/Content/lib/metisMenu/metisMenu.css" rel="stylesheet" />
  11. <link href="~/Content/CSS/index.css" rel="stylesheet" />
  12. @RenderSection("stylesheet", required: false)
  13. <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
  14. <script src="~/Content/lib/zui/js/zui.js"></script>
  15. <script src="~/Content/lib/metisMenu/metisMenu.js"></script>
  16. <script src="~/Content/JS/index.js"></script>
  17.  
  18. </head>
  19. <body>
  20. <!--header-->
  21. <header>
  22. <div class="navbar navbar-inverse " role="navigation">
  23. <div class="navbar-header">
  24. <!--移动设备上的导航切换按钮-->
  25. <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse-example">
  26. <span class="sr-only">切换导航</span>
  27. <span class="icon-bar"></span>
  28. <span class="icon-bar"></span>
  29. <span class="icon-bar"></span>
  30. </button>
  31. <!--品牌名称或logo-->
  32. <a class="navbar-brand">系统后台</a>
  33. </div>
  34. <div class="collapse navbar-collapse navbar-collapse-example">
  35. <ul class="nav navbar-nav navbar-right">
  36. <li><a><i class="icon icon-user"></i>&nbsp;&nbsp;您好,admin</a></li>
  37. <li><a><i class="icon icon-exchange"></i>&nbsp;&nbsp;隐藏菜单</a></li>
  38. <li><a href="/admin/Home"><i class="icon icon-home"></i>&nbsp;&nbsp;首页</a></li>
  39. <li><a><i class="icon icon-question-sign"></i>&nbsp;&nbsp;帮助</a></li>
  40. <li><a><i class="icon icon-off"></i>&nbsp;&nbsp;退出</a></li>
  41. </ul>
  42. </div>
  43. </div>
  44. </header>
  45. <!--header end-->
  46. <!--content-->
  47. <div class="clearfix">
  48. @Html.Partial("_sidebar")
  49. <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 rightmain">
  50. <div class="col-sm-12 col-md-12 rightcontent">
  51. @RenderBody()
  52. </div>
  53. </div>
  54. </div>
  55. <!--content end-->
  56. <!--footer-->
  57. <footer class="col-md-12 footer footerstyle">
  58. <p>&copy; @DateTime.Now.Year - 我的博客系统</p>
  59. </footer>
  60. <!--footer end-->
  61.  
  62. <script src="https://cdn.bootcss.com/jquery-validate/1.17.0/jquery.validate.js"></script>
  63. <script src="https://cdn.bootcss.com/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.js"></script>
  64. <script src="https://cdn.bootcss.com/jquery-ajax-unobtrusive/3.2.4/jquery.unobtrusive-ajax.js"></script>
  65. @RenderSection("scripts", required: false)
  66. </body>
  67. </html>

菜单部分页_sidebar.cshtml代码:

  1. @{
  2. string url = Request.Url.ToString().ToLower();
  3. }
  4. @if (url.Contains("home"))
  5. {
  6. <aside class="col-sm-3 col-md-2 sidebar">
  7. <nav class="sidebar-nav">
  8. <ul class="metismenu" id="menu">
  9. <li class="active">
  10. <a href="#" aria-expanded="true">
  11. <i class="icon icon-github"></i>
  12. 系统统计<i class="fa arrow fa-fw"></i>
  13. </a>
  14. <ul aria-expanded="true">
  15. <li>
  16. <a href="/admin/statistics/visitor">
  17. <i class="icon icon-list"></i>
  18. 访问统计
  19. </a>
  20. </li>
  21. <li>
  22. <a href="/admin/statistics/usesr">
  23. <i class="icon icon-github"></i>
  24. 用户统计
  25. </a>
  26. </li>
  27. </ul>
  28. </li>
  29. <li>
  30. <a href="#" aria-expanded="false">博客管理<i class="fa arrow fa-fw"></i></a>
  31. <ul aria-expanded="false">
  32. <li><a href="/admin/BlogArticle/Index">博客列表</a></li>
  33. <li><a href="/admin/BlogArticle/Add">发布博客</a></li>
  34. </ul>
  35. </li>
  36. <li>
  37. <a href="#" aria-expanded="false">广告管理<i class="fa arrow fa-fw"></i></a>
  38. <ul aria-expanded="false">
  39. <li><a href="@Url.Action("index", "Advertisement")">轮播图管理</a></li>
  40. </ul>
  41. </li>
  42. <li>
  43. <a href="#" aria-expanded="false">用户管理<i class="fa arrow fa-fw"></i></a>
  44. <ul aria-expanded="false">
  45. <li><a href="#">修改信息</a></li>
  46. <li><a href="#">修改密码</a></li>
  47. <li>
  48. <a href="#" aria-expanded="false">用户信息管理<span class="fa plus-times"></span></a>
  49. <ul aria-expanded="false">
  50. <li><a href="#">修改信息</a></li>
  51. <li><a href="#">修改密码</a></li>
  52. </ul>
  53. </li>
  54. </ul>
  55. </li>
  56. <li>
  57. <a href="#" aria-expanded="false">权限管理<i class="fa arrow fa-fw"></i></a>
  58. <ul aria-expanded="false">
  59. <li><a href="#">用户授权</a></li>
  60. <li><a href="#">用户组管理</a></li>
  61. <li><a href="#">用户组授权</a></li>
  62. </ul>
  63. </li>
  64. <li>
  65. <a href="#" aria-expanded="false">日志管理<i class="fa arrow fa-fw"></i></a>
  66. <ul aria-expanded="false">
  67. <li><a href="#">用户日志</a></li>
  68. <li><a href="#">系统日志</a></li>
  69. </ul>
  70. </li>
  71. </ul>
  72. </nav>
  73. </aside>
  74. }
  75. else if (url.Contains("blogarticle"))
  76. {
  77. <aside class="col-sm-3 col-md-2 sidebar">
  78. <nav class="sidebar-nav">
  79. <ul class="metismenu" id="menu">
  80. <li>
  81. <a href="#" aria-expanded="true">
  82. <i class="icon icon-github"></i>
  83. 系统统计<i class="fa arrow fa-fw"></i>
  84. </a>
  85. <ul aria-expanded="true">
  86. <li>
  87. <a href="/admin/statistics/visitor">
  88. <i class="icon icon-list"></i>
  89. 访问统计
  90. </a>
  91. </li>
  92. <li>
  93. <a href="/admin/statistics/usesr">
  94. <i class="icon icon-github"></i>
  95. 用户统计
  96. </a>
  97. </li>
  98. </ul>
  99. </li>
  100. <li class="active">
  101. <a href="#" aria-expanded="false">博客管理<i class="fa arrow fa-fw"></i></a>
  102. <ul aria-expanded="false">
  103. <li><a href="/admin/BlogArticle/Index">博客列表</a></li>
  104. <li><a href="/admin/BlogArticle/Add">发布博客</a></li>
  105. </ul>
  106. </li>
  107. <li>
  108. <a href="#" aria-expanded="false">广告管理<i class="fa arrow fa-fw"></i></a>
  109. <ul aria-expanded="false">
  110. <li><a href="@Url.Action("index", "Advertisement")">轮播图管理</a></li>
  111. </ul>
  112. </li>
  113. <li>
  114. <a href="#" aria-expanded="false">用户管理<i class="fa arrow fa-fw"></i></a>
  115. <ul aria-expanded="false">
  116. <li><a href="#">修改信息</a></li>
  117. <li><a href="#">修改密码</a></li>
  118. <li>
  119. <a href="#" aria-expanded="false">用户信息管理<span class="fa plus-times"></span></a>
  120. <ul aria-expanded="false">
  121. <li><a href="#">修改信息</a></li>
  122. <li><a href="#">修改密码</a></li>
  123. </ul>
  124. </li>
  125. </ul>
  126. </li>
  127. <li>
  128. <a href="#" aria-expanded="false">权限管理<i class="fa arrow fa-fw"></i></a>
  129. <ul aria-expanded="false">
  130. <li><a href="#">用户授权</a></li>
  131. <li><a href="#">用户组管理</a></li>
  132. <li><a href="#">用户组授权</a></li>
  133. </ul>
  134. </li>
  135. <li>
  136. <a href="#" aria-expanded="false">日志管理<i class="fa arrow fa-fw"></i></a>
  137. <ul aria-expanded="false">
  138. <li><a href="#">用户日志</a></li>
  139. <li><a href="#">系统日志</a></li>
  140. </ul>
  141. </li>
  142. </ul>
  143. </nav>
  144. </aside>
  145. }
  146. else if (url.Contains("advertisement"))
  147. {
  148. <aside class="col-sm-3 col-md-2 sidebar">
  149. <nav class="sidebar-nav">
  150. <ul class="metismenu" id="menu">
  151. <li>
  152. <a href="#" aria-expanded="true">
  153. <i class="icon icon-github"></i>
  154. 系统统计<i class="fa arrow fa-fw"></i>
  155. </a>
  156. <ul aria-expanded="true">
  157. <li>
  158. <a href="/admin/statistics/visitor">
  159. <i class="icon icon-list"></i>
  160. 访问统计
  161. </a>
  162. </li>
  163. <li>
  164. <a href="/admin/statistics/usesr">
  165. <i class="icon icon-github"></i>
  166. 用户统计
  167. </a>
  168. </li>
  169. </ul>
  170. </li>
  171. <li>
  172. <a href="#" aria-expanded="false">博客管理<i class="fa arrow fa-fw"></i></a>
  173. <ul aria-expanded="false">
  174. <li><a href="/admin/BlogArticle/Index">博客列表</a></li>
  175. <li><a href="/admin/BlogArticle/Add">发布博客</a></li>
  176. </ul>
  177. </li>
  178. <li class="active">
  179. <a href="#" aria-expanded="false">广告管理<i class="fa arrow fa-fw"></i></a>
  180. <ul aria-expanded="false">
  181. <li><a href="@Url.Action("index", "Advertisement")">轮播图管理</a></li>
  182. </ul>
  183. </li>
  184. <li>
  185. <a href="#" aria-expanded="false">用户管理<i class="fa arrow fa-fw"></i></a>
  186. <ul aria-expanded="false">
  187. <li><a href="#">修改信息</a></li>
  188. <li><a href="#">修改密码</a></li>
  189. <li>
  190. <a href="#" aria-expanded="false">用户信息管理<span class="fa plus-times"></span></a>
  191. <ul aria-expanded="false">
  192. <li><a href="#">修改信息</a></li>
  193. <li><a href="#">修改密码</a></li>
  194. </ul>
  195. </li>
  196. </ul>
  197. </li>
  198. <li>
  199. <a href="#" aria-expanded="false">权限管理<i class="fa arrow fa-fw"></i></a>
  200. <ul aria-expanded="false">
  201. <li><a href="#">用户授权</a></li>
  202. <li><a href="#">用户组管理</a></li>
  203. <li><a href="#">用户组授权</a></li>
  204. </ul>
  205. </li>
  206. <li>
  207. <a href="#" aria-expanded="false">日志管理<i class="fa arrow fa-fw"></i></a>
  208. <ul aria-expanded="false">
  209. <li><a href="#">用户日志</a></li>
  210. <li><a href="#">系统日志</a></li>
  211. </ul>
  212. </li>
  213. </ul>
  214. </nav>
  215. </aside>
  216. }

其实我这个菜单选中的效果做的很垃圾,我自己都觉得不要,但是目前我也只能想到这个方法,因为每次加载一个嵌套的页面就会从新去加载一次布局页_Layout.cshtml的内容,我这个菜单是有一个active选中的样式的,这个是菜单插件里面已经写好了,这里遇到的问题就是每次刷新都会把页面选中效果设置到默认的菜单上,假如点击了发布博客菜单应该显示博客管理这个菜单内容,但是从新加载的时候就会回到默认的系统统计菜单上,所以这里就用地址路径来判断应该显示那个菜单,方法真的很笨,见谅,各位。

2.2博客信息添加功能实现

在52MVCBlog.Model程序集的Models文件创建一个BlogArticle类,然后在创建一个文件VeiwModels,Models文件夹里面的类是用来生成数据库对应的表,而VeiwModels文件夹里面对应的类是用来在view视图页面展示数据用的,当你一个表字段很多不需要所有数据都展示,或者要做一些处理计算的类,这样就需要一个VeiwModels类来分离。

BlogArticle类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace _52MVCBlog.Model.Models
  8. {
  9.  
  10. /// <summary>
  11. /// 博客文章
  12. /// </summary
  13. public class BlogArticle
  14. {
  15. /// <summary>
  16. ///
  17. /// </summary>
  18. public int bID { get; set; }
  19. /// <summary>
  20. /// 创建人
  21. /// </summary>
  22. public string bsubmitter { get; set; }
  23.  
  24. /// <summary>
  25. /// 博客标题
  26. /// </summary>
  27. public string btitle { get; set; }
  28.  
  29. /// <summary>
  30. /// 类别
  31. /// </summary>
  32. public string bcategory { get; set; }
  33.  
  34. /// <summary>
  35. /// 内容
  36. /// </summary>
  37. public string bcontent { get; set; }
  38.  
  39. /// <summary>
  40. /// 访问量
  41. /// </summary>
  42. public int btraffic { get; set; }
  43.  
  44. /// <summary>
  45. /// 评论数量
  46. /// </summary>
  47. public int bcommentNum { get; set; }
  48.  
  49. /// <summary>
  50. /// 修改时间
  51. /// </summary>
  52. public DateTime bUpdateTime { get; set; }
  53.  
  54. /// <summary>
  55. /// 创建时间
  56. /// </summary>
  57. public System.DateTime bCreateTime { get; set; }
  58. /// <summary>
  59. /// 备注
  60. /// </summary>
  61. public string bRemark { get; set; }
  62. }
  63. }

BlogViewModels类:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace _52MVCBlog.Model.Models
  8. {
  9. /// <summary>
  10. /// 博客信息展示类
  11. /// </summary>
  12. public class BlogViewModels
  13. {
  14. /// <summary>
  15. ///
  16. /// </summary>
  17. public int bID { get; set; }
  18. /// <summary>
  19. /// 创建人
  20. /// </summary>
  21. public string bsubmitter { get; set; }
  22.  
  23. /// <summary>
  24. /// 博客标题
  25. /// </summary>
  26. public string btitle { get; set; }
  27.  
  28. /// <summary>
  29. /// 摘要
  30. /// </summary>
  31. public string digest { get; set; }
  32.  
  33. /// <summary>
  34. /// 上一篇
  35. /// </summary>
  36. public string previous { get; set; }
  37.  
  38. /// <summary>
  39. /// 上一篇id
  40. /// </summary>
  41. public int previousID { get; set; }
  42.  
  43. /// <summary>
  44. /// 下一篇
  45. /// </summary>
  46. public string next { get; set; }
  47.  
  48. /// <summary>
  49. /// 下一篇id
  50. /// </summary>
  51. public int nextID { get; set; }
  52.  
  53. /// <summary>
  54. /// 类别
  55. /// </summary>
  56. public string bcategory { get; set; }
  57.  
  58. /// <summary>
  59. /// 内容
  60. /// </summary>
  61. public string bcontent { get; set; }
  62.  
  63. /// <summary>
  64. /// 访问量
  65. /// </summary>
  66. public int btraffic { get; set; }
  67.  
  68. /// <summary>
  69. /// 评论数量
  70. /// </summary>
  71. public int bcommentNum { get; set; }
  72.  
  73. /// <summary>
  74. /// 修改时间
  75. /// </summary>
  76. public DateTime bUpdateTime { get; set; }
  77.  
  78. /// <summary>
  79. /// 创建时间
  80. /// </summary>
  81. public System.DateTime bCreateTime { get; set; }
  82. /// <summary>
  83. /// 备注
  84. /// </summary>
  85. public string bRemark { get; set; }
  86. }
  87. }

在maps文件夹中添加相应的约束

BlogArticleMap类:

  1. using _52MVCBlog.Model.Models;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Data.Entity.ModelConfiguration;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace _52MVCBlog.Model.Maps
  10. {
  11. public class BlogArticleMap: EntityTypeConfiguration<BlogArticle>
  12. {
  13. public BlogArticleMap()
  14. {
  15. this.HasKey(p => p.bID);
  16. this.Property(p => p.btitle).HasMaxLength();
  17. this.Property(p => p.bsubmitter).HasMaxLength();
  18. this.Property(p => p.bcontent).HasColumnType("Text").IsMaxLength();
  19. }
  20. }
  21. }

然后在控制台使用更新数据库命令:add-migration 52MVCBlogDB与update database -force,一定要选择model层(如果出现update : 无法将“update”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。执行Install-Package EntityFramework后重试即可)

创建好了表,然后就是在仓储层以及业务层创建相应的接口和实现类

  IBlogArticleRepository接口类代码:

  1. using _52MVCBlog.IRepository.Base;
  2. using _52MVCBlog.Model.Models;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace _52MVCBlog.IRepository
  10. {
  11. public interface IBlogArticleRepository : IBaseRepository<BlogArticle>
  12. {
  13. }
  14. }

  BlogArticleRepository类代码:

  1. using _52MVCBlog.IRepository;
  2. using _52MVCBlog.Model.Models;
  3. using _52MVCBlog.Repository.Base;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Threading.Tasks;
  9.  
  10. namespace _52MVCBlog.Repository
  11. {
  12. public class BlogArticleRepository : BaseRepository<BlogArticle>, IBlogArticleRepository
  13. {
  14. }
  15. }

在52MVCBlog.Common程序集下新建ToolsHelper文件夹,新建Tools.cs公共工具类

  Tools公共工具类代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Web;
  7. using System.IO;
  8.  
  9. namespace _52MVCBlog.Common.ToolsHelper
  10. {
  11. /// <summary>
  12. /// 公共实用工具
  13. /// </summary>
  14. public class Tools
  15. {
  16. #region 计算两个时间差值的函数,返回时间差的绝对值
  17. /// <summary>
  18. /// 计算两个时间差值的函数,返回时间差的绝对值:
  19. /// </summary>
  20. /// <param name="DateTime1"></param>
  21. /// <param name="DateTime2"></param>
  22. /// <returns></returns>
  23. public string DateDiff(DateTime DateTime1, DateTime DateTime2)
  24. {
  25. string dateDiff = null;
  26. try
  27. {
  28. TimeSpan ts1 = new TimeSpan(DateTime1.Ticks);
  29. TimeSpan ts2 = new TimeSpan(DateTime2.Ticks);
  30. TimeSpan ts = ts1.Subtract(ts2).Duration();
  31. dateDiff = ts.Days.ToString() + "天"
  32. + ts.Hours.ToString() + "小时"
  33. + ts.Minutes.ToString() + "分钟"
  34. + ts.Seconds.ToString() + "秒";
  35. }
  36. catch
  37. {
  38. }
  39. return dateDiff;
  40. }
  41. #endregion
  42.  
  43. #region 去除富文本中的HTML标签
  44. /// <summary>
  45. /// 去除富文本中的HTML标签
  46. /// </summary>
  47. /// <param name="html"></param>
  48. /// <param name="length"></param>
  49. /// <returns></returns>
  50. public static string ReplaceHtmlTag(string html, int length = )
  51. {
  52. string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", "");
  53. strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", "");
  54. if (length>&&strText.Length>length)
  55. {
  56. return strText.Substring(, length);
  57. }
  58. return strText;
  59. }
  60. #endregion
  61.  
  62. #region 上传文件方法,默认生成日期文件夹,MVC使用
  63. /// <summary>
  64. /// 上传文件方法,默认生成日期文件夹,MVC使用
  65. /// 返回文件名
  66. /// </summary>
  67. /// <param name="PostedFile">mvc后台获取的</param>
  68. /// <param name="allowExtensions">允许上传的扩展文件名类型,如:string[] allowExtensions = { ".doc", ".xls", ".ppt", ".jpg", ".gif" };</param>
  69. /// <param name="maxLength">允许上传的最大大小,以M为单位</param>
  70. /// <param name="savePath">保存文件的目录,注意是绝对路径,如:Server.MapPath("~/upload/");</param>
  71. /// <param name="gendatedir">是否生成日期文件夹</param>
  72. /// <param name="guidname">是否是GUID名字,默认true</param>
  73. /// <param name="savename">保存文件名(不带后缀),如果非空则以此文件名保存</param>
  74. public static string Upload_MVC(HttpPostedFileBase PostedFile, string[] allowExtensions, int maxLength, string savePath, bool gendatedir = true, bool guidname = true, string savename = "")
  75. {
  76. //文件格式是否允许上传
  77. bool fileAllow = false;
  78.  
  79. //检查文件大小,ContentLength获取的是字节,转成M的时候要除以2次1024
  80. if (PostedFile.ContentLength//>=maxLength)
  81. {
  82. throw new Exception("只能上传小于" + maxLength + "M的文件!");
  83. }
  84.  
  85. //取得长传文件的扩展名,并转换成小写字母
  86. string fileExtension = System.IO.Path.GetExtension(PostedFile.FileName).ToLower();
  87. string tmp = "";//存储允许上传的文件的后缀名
  88. //检查扩展文件名是否符合限定类型
  89. for (int i = ; i < allowExtensions.Length; i++)
  90. {
  91. tmp+=i==allowExtensions.Length-?allowExtensions[i]:allowExtensions[i] + ",";
  92. if (fileExtension==allowExtensions[i])
  93. {
  94. fileAllow = true;
  95. }
  96. }
  97.  
  98. if (fileAllow)
  99. {
  100. try
  101. {
  102. string dateDir = DateTime.Now.ToString("yyyyMMdd");
  103. if (!Directory.Exists(savePath+dateDir)&&gendatedir)
  104. {
  105. Directory.CreateDirectory(savePath + dateDir);
  106. }
  107. string saveName = guidname ? Guid.NewGuid() + fileExtension : PostedFile.FileName;
  108. if (!string.IsNullOrEmpty(savename))
  109. {
  110. saveName = savename + fileExtension;
  111. }
  112. string path = gendatedir ? savePath + dateDir + "/" + saveName : savePath + saveName;
  113. //存储文件到文件夹
  114. PostedFile.SaveAs(path);
  115. return gendatedir ? dateDir + "/" + saveName : saveName;
  116. }
  117. catch (Exception ex)
  118. {
  119.  
  120. throw new Exception(ex.Message);
  121. }
  122. }
  123. else
  124. {
  125. throw new Exception("文件格式(" + fileExtension + ")不符,可以上传的文件格式为:" + tmp);
  126. }
  127. }
  128. #endregion
  129. }
  130. }

  IBlogArticleServices接口类代码:

  1. using _52MVCBlog.IService.Base;
  2. using _52MVCBlog.Model.Models;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Text;
  7. using System.Threading.Tasks;
  8.  
  9. namespace _52MVCBlog.IService
  10. {
  11. public interface IBlogArticleServices : IBaseServices<BlogArticle>
  12. {
  13. /// <summary>
  14. /// 获取视图博客详情信息
  15. /// </summary>
  16. /// <param name="id"></param>
  17. /// <returns></returns>
  18. BlogViewModels getBlogDetails(int id);
  19. }
  20. }

  BlogArticleServices类代码:

  1. using _52MVCBlog.Common.ToolsHelper;
  2. using _52MVCBlog.IRepository;
  3. using _52MVCBlog.IService;
  4. using _52MVCBlog.Model.Models;
  5. using _52MVCBlog.Service.Base;
  6. using AutoMapper;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Threading.Tasks;
  12.  
  13. namespace _52MVCBlog.Service
  14. {
  15. public class BlogArticleServices : BaseServices<BlogArticle>, IBlogArticleServices
  16. {
  17. #region Autofac依赖注入
  18. private IBlogArticleRepository dal;
  19.  
  20. public BlogArticleServices(IBlogArticleRepository dal)
  21. {
  22. this.dal = dal;
  23. base.baseDal = dal;
  24. }
  25. #endregion
  26.  
  27. /// <summary>
  28. /// 获取视图博客详情信息
  29. /// </summary>
  30. /// <param name="id"></param>
  31. /// <returns></returns>
  32. public BlogViewModels getBlogDetails(int id)
  33. {
  34. BlogArticle blogArticle = dal.QueryWhere(a => a.bID == id).FirstOrDefault();
  35. BlogArticle nextblog = dal.QueryWhere(a => a.bID == id - ).FirstOrDefault();
  36. BlogArticle prevblog = dal.QueryWhere(a => a.bID == id + ).FirstOrDefault();
  37. blogArticle.btraffic += ;
  38. dal.Edit(blogArticle, new string[] { "btraffic" });
  39. dal.SaverChanges();
  40. //AutoMapper自动映射
  41. //注册映射
  42. Mapper.Initialize(cfg => cfg.CreateMap<BlogArticle, BlogViewModels>());
  43. //进行映射
  44. BlogViewModels models = Mapper.Map<BlogArticle, BlogViewModels>(blogArticle);
  45. if (nextblog != null)
  46. {
  47. models.next = nextblog.btitle;
  48. models.nextID = nextblog.bID;
  49. }
  50.  
  51. if (prevblog != null)
  52. {
  53. models.previous = prevblog.btitle;
  54. models.previousID = prevblog.bID;
  55. }
  56.  
  57. models.digest = Tools.ReplaceHtmlTag(blogArticle.bcontent).Length > ? Tools.ReplaceHtmlTag(blogArticle.bcontent).Substring(, ) : Tools.ReplaceHtmlTag(blogArticle.bcontent);
  58. return models;
  59. }
  60. }
  61. }

2.3博客添加页面实现功能

在区域admin的控制器下创建一个Add方法用来展示页面。

  Add方法:

  1. public ActionResult Add()
  2. {
  3. return View();
  4. }

然后View添加视图选择使用布局页

  Add局页代码:

  1. @{
  2. ViewBag.Title = "添加博客";
  3. }
  4.  
  5. <link href="~/Content/animate.css" rel="stylesheet" />
  6. <link href="~/Content/CSS/blogArticleStyle.css" rel="stylesheet" />
  7. <script src="https://unpkg.com/wangeditor/release/wangEditor.min.js"></script>
  8. <script src="https://cdn.bootcss.com/jquery-ajax-unobtrusive/3.2.4/jquery.unobtrusive-ajax.js"></script>
  9.  
  10. <script type="text/javascript">
  11. $(function () {
  12.  
  13. // 获取元素
  14. var E = window.wangEditor;
  15. // 生成编辑器
  16. var editor = new E("#bcontent");
  17. // 自定义菜单
  18. editor.customConfig.menus = [
  19. 'head', // 标题
  20. 'bold', // 粗体
  21. 'italic', // 斜体
  22. 'underline', // 下划线
  23. 'strikeThrough', // 删除线
  24. 'foreColor', // 文字颜色
  25. 'backColor', // 背景颜色
  26. 'link', // 插入链接
  27. 'list', // 列表
  28. 'justify', // 对齐方式
  29. 'quote', // 引用
  30. 'emoticon', // 表情
  31. 'image', // 插入图片
  32. 'table', // 表格
  33. 'video', // 插入视频
  34. 'code', // 插入代码
  35. 'undo', // 撤销
  36. 'redo' // 重复
  37. ];
  38. //上传图片(举例)
  39. editor.customConfig.uploadImgServer = '/admin/BlogArticle/upload';
  40. //editor.customConfig.debug = true;
  41. // 将 timeout 时间改为 3s
  42. editor.customConfig.uploadImgTimeout = ;
  43. editor.customConfig.uploadImgHooks = {
  44. //before: function (xhr, editor, files) {
  45. // // 图片上传之前触发
  46. // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件
  47.  
  48. // // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传
  49. // // return {
  50. // // prevent: true,
  51. // // msg: '放弃上传'
  52. // // }
  53. // alert("before");
  54.  
  55. //},
  56. //success: function (xhr, editor, result) {
  57. // // 图片上传并返回结果,图片插入成功之后触发
  58. // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
  59. // alert("success");
  60.  
  61. //},
  62. //fail: function (xhr, editor, result) {
  63. // alert("fail");
  64. // // 图片上传并返回结果,但图片插入错误时触发
  65. // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果
  66. //},
  67. //error: function (xhr, editor) {
  68. // // 图片上传出错时触发
  69. // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
  70. // alert("error");
  71.  
  72. //},
  73. //timeout: function (xhr, editor) {
  74. // // 图片上传超时时触发
  75. // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象
  76. // alert("timeout");
  77.  
  78. //},
  79.  
  80. // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
  81. // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
  82. customInsert: function (insertImg, result, editor) {
  83. // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
  84. // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
  85.  
  86. // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
  87. var url = JSON.parse(result).data[]
  88. insertImg(url)
  89.  
  90. // result 必须是一个 JSON 格式字符串!!!否则报错
  91. alert("customInsert");
  92.  
  93. }
  94. }
  95. editor.create();
  96. });
  97.  
  98. //添加博文之后
  99. function afterAddBlog(data) {
  100. var serverData = data.split(':');
  101. if (serverData[] == "ok") {
  102. alert(serverData[]);
  103. window.location.reload();
  104. }
  105. };
  106. </script>
  107.  
  108. <div class="blogcontent">
  109. <!-- head star -->
  110. <div class="tnav row border-bottom white-bg page-heading">
  111. <div class="col-sm-4">
  112. <h2 class="fl">博客后台</h2>
  113. <ol class="breadcrumb fl">
  114. <li><a href="/admin/Home">博客管理</a></li>
  115. <li><strong>发布博客</strong></li>
  116. </ol>
  117. </div>
  118. </div>
  119. <!-- head end -->
  120. <!-- form star -->
  121. <div class="">
  122. <div class="wrapper wrapper-content animated fadeInUp" style="height:600px;padding-bottom:30px;overflow:auto">
  123. @using (Ajax.BeginForm("Add", "BlogArticle", new { }, new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterAddBlog" }, new { @class = "form-horizontal" }))
  124. {
  125. <div class="form-group">
  126. <label class="col-md-1 control-label">标题&nbsp;:</label>
  127. <div class="col-md-11">
  128. <input type='text' name='btitle' id='title' value='' class='form-control' placeholder='' />
  129. </div>
  130. </div>
  131. <div class="form-group">
  132. <label class="col-md-1 control-label">类别&nbsp;:</label>
  133. <div class='col-md-2'>
  134. <select name='bcategory' id='original' class='form-control'>
  135. <option value='技术博文' selected='selected'>技术博文</option>
  136. <option value='随笔日志'>随笔日志</option>
  137. </select>
  138. </div>
  139. </div>
  140. <div class="form-group">
  141. <label class="col-md-1 control-label">内容&nbsp;:</label>
  142. <div class='col-md-11'>
  143. <div id="bcontent" class="text">
  144. <p>请输入内容...</p>
  145. </div>
  146. </div>
  147. </div>
  148. <div class="form-group">
  149. <div class="col-md-offset-1 col-md-10">
  150. <input type='submit' id='submit' class='btn btn-info' value='保存' data-loading='稍候...' />
  151. </div>
  152. </div>
  153. }
  154. </div>
  155. </div>
  156. <!-- form end -->
  157. </div>

效果图

在控制器中添加一个上传图片的方法upload,用于富文本编辑器上传图片

注意:wangEditor3使用手册有部分bug,后台必须返回给前台json格式,并且要通过监听函数进行解析显示图片

  upload代码:

  1. public ActionResult upload()
  2. {
  3. //文件保存目录路径
  4. String savePath = "/upload/";
  5.  
  6. //定义允许上传的文件扩展名
  7. Hashtable extTable = new Hashtable();
  8. extTable.Add("image", "gif,jpg,jpeg,png,bmp");
  9. extTable.Add("flash", "swf,flv");
  10. extTable.Add("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb");
  11. extTable.Add("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2");
  12.  
  13. //最大文件大小
  14. int maxSize = ;
  15.  
  16. HttpPostedFileBase imgFile = Request.Files[];
  17. if (imgFile == null)
  18. return Content("error|请选择文件。");
  19.  
  20. String dirPath = Server.MapPath(savePath);
  21. if (!Directory.Exists(dirPath))
  22. Directory.CreateDirectory(dirPath);
  23.  
  24. String dirName = Request.QueryString["dir"];
  25. if (String.IsNullOrEmpty(dirName))
  26. dirName = "image";
  27. if (!extTable.ContainsKey(dirName))
  28. return Content("error|目录名不正确。");
  29.  
  30. String fileName = imgFile.FileName;
  31. String fileExt = Path.GetExtension(fileName).ToLower();
  32.  
  33. if (imgFile.InputStream == null || imgFile.InputStream.Length > maxSize)
  34. return Content("error|上传文件大小超过限制。");
  35.  
  36. if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(((String)extTable[dirName]).Split(','), fileExt.Substring().ToLower()) == -)
  37. return Content("error|上传文件扩展名是不允许的扩展名。\n只允许" + ((String)extTable[dirName]) + "格式。");
  38.  
  39. //创建文件夹
  40. dirPath += dirName + "/";
  41. if (!Directory.Exists(dirPath))
  42. Directory.CreateDirectory(dirPath);
  43. String ymd = DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo);
  44. dirPath += ymd + "/";
  45. if (!Directory.Exists(dirPath))
  46. Directory.CreateDirectory(dirPath);
  47.  
  48. String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", DateTimeFormatInfo.InvariantInfo) + fileExt;
  49. String filePath = dirPath + newFileName;
  50.  
  51. imgFile.SaveAs(filePath);
  52.  
  53. String fileUrl = "http://" + Request.Url.Authority + savePath + "image/" + ymd + "/" + newFileName;
  54. JObject jObj=new JObject();
  55. jObj.Add("errno", );
  56. jObj.Add("data", new JArray(fileUrl));
  57. return Json(JsonConvert.SerializeObject(jObj));
  58. }

提交博客使用的是异步提交

  add方法:

  1. @{
  2. ViewBag.Title = "添加博客";
  3. }
  4.  
  5. <link href="~/Content/animate.css" rel="stylesheet" />
  6. <link href="~/Content/CSS/blogArticleStyle.css" rel="stylesheet" />
  7. <script src="https://unpkg.com/wangeditor/release/wangEditor.min.js"></script>
  8. @*<script src="https://cdn.bootcss.com/jquery-ajax-unobtrusive/3.2.4/jquery.unobtrusive-ajax.js"></script>*@
  9.  
  10. <script type="text/javascript">
  11. $(function () {
  12.  
  13. // 获取元素
  14. var E = window.wangEditor;
  15. // 生成编辑器
  16. var editor = new E("#bcontentdiv");
  17. // 自定义菜单
  18. editor.customConfig.menus = [
  19. 'head', // 标题
  20. 'bold', // 粗体
  21. 'italic', // 斜体
  22. 'underline', // 下划线
  23. 'strikeThrough', // 删除线
  24. 'foreColor', // 文字颜色
  25. 'backColor', // 背景颜色
  26. 'link', // 插入链接
  27. 'list', // 列表
  28. 'justify', // 对齐方式
  29. 'quote', // 引用
  30. 'emoticon', // 表情
  31. 'image', // 插入图片
  32. 'table', // 表格
  33. 'video', // 插入视频
  34. 'code', // 插入代码
  35. 'undo', // 撤销
  36. 'redo' // 重复
  37. ];
  38. //上传图片(举例)
  39. editor.customConfig.uploadImgServer = '/admin/BlogArticle/upload';
  40. //editor.customConfig.debug = true;
  41. // 将 timeout 时间改为 3s
  42. editor.customConfig.uploadImgTimeout = ;
  43. editor.customConfig.uploadImgHooks = {
  44. // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
  45. // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错)
  46. customInsert: function (insertImg, result, editor) {
  47. // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!)
  48. // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果
  49.  
  50. // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片:
  51. var url = JSON.parse(result).data[]
  52. insertImg(url)
  53.  
  54. // result 必须是一个 JSON 格式字符串!!!否则报错
  55. alert("customInsert");
  56.  
  57. }
  58. }
  59. //wangEditor 从v3版本开始不支持 textarea ,但是可以通过onchange来实现 textarea 中提交富文本内容。
  60. var $text1 = $('#bcontent')
  61. editor.customConfig.onchange = function (html) {
  62. // 监控变化,同步更新到 textarea
  63. $text1.val(html)
  64. }
  65. editor.create();
  66. });
  67.  
  68. //添加博文之后
  69. function afterAddBlog(data) {
  70. var serverData = data.split(':');
  71. if (serverData[] == "ok") {
  72. alert(serverData[]);
  73. window.location.reload();
  74. }
  75. };
  76. </script>
  77.  
  78. <div class="blogcontent">
  79. <!-- head star -->
  80. <div class="tnav row border-bottom white-bg page-heading">
  81. <div class="col-sm-4">
  82. <h2 class="fl">博客后台</h2>
  83. <ol class="breadcrumb fl">
  84. <li><a href="/admin/Home">博客管理</a></li>
  85. <li><strong>发布博客</strong></li>
  86. </ol>
  87. </div>
  88. </div>
  89. <!-- head end -->
  90. <!-- form star -->
  91. <div class="">
  92. <div class="wrapper wrapper-content animated fadeInUp" style="height:600px;padding-bottom:30px;overflow:auto">
  93. @using (Ajax.BeginForm("Add", "BlogArticle", new { }, new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterAddBlog" }, new { @class = "form-horizontal" }))
  94. {
  95. <div class="form-group">
  96. <label class="col-md-1 control-label">标题&nbsp;:</label>
  97. <div class="col-md-11">
  98. <input type='text' name='btitle' id='title' value='' class='form-control' placeholder='' />
  99. </div>
  100. </div>
  101. <div class="form-group">
  102. <label class="col-md-1 control-label">类别&nbsp;:</label>
  103. <div class='col-md-2'>
  104. <select name='bcategory' id='original' class='form-control'>
  105. <option value='技术博文' selected='selected'>技术博文</option>
  106. <option value='随笔日志'>随笔日志</option>
  107. </select>
  108. </div>
  109. </div>
  110. <div class="form-group">
  111. <label class="col-md-1 control-label">内容&nbsp;:</label>
  112. <div class='col-md-11'>
  113. <div id="bcontentdiv" class="text">
  114. <p>请输入内容...</p>
  115. </div>
  116. <textarea id="bcontent" rows="" name="bcontent" class='form-control hidden'>
  117. </textarea>
  118. </div>
  119. </div>
  120. <div class="form-group">
  121. <div class="col-md-offset-1 col-md-10">
  122. <input type='submit' id='submit' class='btn btn-info' value='保存' data-loading='稍候...' />
  123. </div>
  124. </div>
  125. }
  126. </div>
  127. </div>
  128. <!-- form end -->
  129. </div>

记住在使用之前需要把接口和对应的方法实现在构造方法中调用

ps:可能会遇到执行两次Ajax.BeginForm的情况,原因是多引用了一次jquery.unobtrusive-ajax.js文件,删掉即可。

三、博客系统前台布局实现

3.1接下来就改前台展示部分,同样使用的是布局页

设计页面如下:

  前台布局页_Layout.cshtml代码:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <meta charset="utf-8" />
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <link href="~/Content/lib/zui/css/zui.css" rel="stylesheet" />
  8. <link href="~/Content/CSS/zui-blog-theme.css" rel="stylesheet" />
  9. <link href="~/Content/CSS/zui-theme-blue.css" rel="stylesheet" />
  10. <link href="~/Content/CSS/HomeIndex.css" rel="stylesheet" />
  11. <link href="~/Content/CSS/pagerstyles.css" rel="stylesheet" />
  12. <title>@ViewBag.Title - 52MVC博客</title>
  13. </head>
  14. <body>
  15. <!--导航部分-->
  16. @Html.Partial("_NavbarPage")
  17. <!--导航部分-->
  18. <!--主体内容-->
  19. <div class="main">
  20. <div class="row">
  21.  
  22. <!--左边主要内容-->
  23. @*<article style="margin-top: 10px;">
  24. <div class="col-md-8" id="leftmain">
  25. @RenderBody()
  26. </div>
  27. </article>*@
  28.  
  29. <!--左边主要内容-->
  30. <!--右边栏-->
  31. @{
  32. if (ViewBag.controllername != "statistical")
  33. {
  34. <article style="margin-top: 10px;">
  35. <div class="col-md-8" id="leftmain">
  36. @RenderBody()
  37. </div>
  38. </article>
  39. @Html.Partial("_RightPage")
  40. }
  41. else
  42. {
  43. @RenderBody()
  44. }
  45. }
  46. <!--右边栏-->
  47. </div>
  48. </div>
  49. <!--主体内容-->
  50. <!--底部版权部分-->
  51. @Html.Partial("_FooterPage")
  52.  
  53. <script src="~/Content/lib/jquery-3.2.1.min.js"></script>
  54. <script src="~/Content/lib/zui/js/zui.js"></script>
  55. <script src="~/Content/lib/jquery.validate.js"></script>
  56. <script src="~/Content/lib/jquery.validate.unobtrusive.js"></script>
  57. <script src="~/Content/lib/jquery.unobtrusive-ajax.js"></script>
  58.  
  59. <script type="text/javascript">
  60. $(function () {
  61. //用于控制导航样式
  62. var name = '@ViewBag.controllername'
  63. $('#' + name).attr("class", "active")
  64. })
  65. </script>
  66. @RenderSection("scripts", false)
  67. <!--底部版权部分-->
  68. </body>
  69. </html>

  部分布局页导航部分_NavbarPage代码:

  1. <!--导航-->
  2. <nav class="navbar navbar-default navbar-fixed-top">
  3. <div class="container">
  4. <!--小屏幕导航按钮和logo-->
  5. <div class="navbar-header">
  6. <button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
  7. <span class="icon-bar"></span>
  8. <span class="icon-bar"></span>
  9. <span class="icon-bar"></span>
  10. </button>
  11. <a href="index.html" class="navbar-brand"> Blog</a>
  12.  
  13. </div>
  14. <!--小屏幕导航按钮和logo-->
  15. <!--导航-->
  16. <div class="navbar-collapse collapse">
  17. <ul class="nav navbar-nav">
  18. <li id="home"><a href="/home/index" id="index"><i class="icon icon-home"></i>&nbsp;首页</a></li>
  19. <li id="blog"><a href="/blog/index" id="content"><i class="icon icon-list-alt"></i>&nbsp;博文</a></li>
  20. <li><a href="/movie/index"><i class="icon icon-film"></i>&nbsp;随笔</a></li>
  21. <li><a href="/statistical/index"><i class="icon icon-bar-chart"></i>&nbsp;访问</a></li>
  22. <li><a href="/about/index"><span class="icon icon-tags"></span>&nbsp;关于</a></li>
  23. </ul>
  24. <form class="navbar-form navbar-right" role="search">
  25. <div class="form-group">
  26. <input type="text" class="form-control" placeholder="搜索">
  27. </div>
  28. <button type="submit" class="btn btn-primary"><i class="icon icon-search"></i>&nbsp;搜索</button>
  29. </form>
  30. </div>
  31. <!--导航-->
  32. </div>
  33. </nav>
  34. <!--导航-->

在52MVCBlog.Model程序集下的Models添加查询统计留言排行用的一个类TopgbViewModels.cs代码:

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace _52MVCBlog.Model.Models
  8. {
  9. /// <summary>
  10. /// 留言排名展示类
  11. /// </summary>
  12. public class TopgbViewModels
  13. {
  14. /// <summary>
  15. /// 博客ID
  16. /// </summary>
  17. public int? blogId { get; set; }
  18.  
  19. /// <summary>
  20. /// 评论数量
  21. /// </summary>
  22. public int counts { get; set; }
  23.  
  24. /// <summary>
  25. /// 博客标题
  26. /// </summary>
  27. public string btitle { get; set; }
  28. }
  29. }

  部分布局页右侧统计部分_RightPage代码:

  1. <!--右边栏部分-->
  2. @using _52MVCBlog.Model.Models;
  3. <aside>
  4. <div class="col-md-4">
  5. <section class="youbianlan">
  6. <div class="panel-group">
  7. <div class="panel">
  8. <div class="panel-heading">
  9. <div class="panel-title panel-info">
  10. <h4>最新发布</h4>
  11. </div>
  12. </div>
  13. <div class="panel-body">
  14. <ul>
  15. @{
  16. if (ViewBag.blogtimelist != null)
  17. {
  18. for (int i = ; i < ViewBag.blogtimelist.Count; i++)
  19. {
  20. <li><a href="/blog/Detail/@ViewBag.blogtimelist[i].bID">@ViewBag.blogtimelist[i].btitle</a></li>
  21. }
  22. }
  23. }
  24. </ul>
  25. </div>
  26. </div>
  27. </div>
  28. </section>
  29. <section class="youbianlan">
  30. <div class="panel-group">
  31. <div class="panel">
  32. <div class="panel-heading">
  33. <div class="panel-title panel-info">
  34. <h4>阅读排行榜</h4>
  35. </div>
  36. </div>
  37. <div class="panel-body">
  38. <ul>
  39. @{
  40. if (ViewBag.blogtrafficlist != null)
  41. {
  42. for (int i = ; i < ViewBag.blogtrafficlist.Count; i++)
  43. {
  44. <li><a href="/blog/Detail/@ViewBag.blogtrafficlist[i].bID">@ViewBag.blogtrafficlist[i].btitle</a></li>
  45. }
  46. }
  47. }
  48. </ul>
  49. </div>
  50. </div>
  51. </div>
  52. </section>
  53. <section class="youbianlan">
  54. <div class="panel-group">
  55. <div class="panel">
  56. <div class="panel-heading">
  57. <div class="panel-title panel-info">
  58. <h4>评论排行榜</h4>
  59.  
  60. </div>
  61. </div>
  62. <div class="panel-body">
  63. <ul>
  64. @{
  65. List<TopgbViewModels> list = ViewBag.blogguestbooklist as List<TopgbViewModels>;
  66. if (list != null && list.Any())
  67. {
  68. if (list.Count < )
  69. {
  70. for (int i = ; i < list.Count; i++)
  71. {
  72. <li><a href="/blog/Detail/@list[i].blogId">@list[i].btitle</a></li>
  73. }
  74. }
  75. else
  76. {
  77. for (int i = ; i < list.Count; i++)
  78. {
  79. <li><a href="/blog/Detail/@list[i].blogId">@list[i].btitle</a></li>
  80. }
  81. }
  82.  
  83. }
  84.  
  85. }
  86. </ul>
  87. </div>
  88. </div>
  89. </div>
  90. </section>
  91. </div>
  92. </aside>
  93. <!--右边栏部分-->

  部分布局页底部版权部分_FooterPage代码:

  1. <!--页脚部分-->
  2. <div id="footer_wrapper" class="col-md-12">
  3. <footer>
  4. <ul>
  5. <li><a href="content.html">版权信息</a></li>
  6. <li><a href="content.html">站点地图</a></li>
  7. <li><a href="content.html">联系我们</a></li>
  8. </ul>
  9. <p>Copyright © 52Blog</p>
  10. </footer>
  11. </div>
  12. <!--页脚部分-->

在52MVCBlog.Model程序集下添加Guestbook,GuestbookMap,Advertisement,AdvertisementMap,GuestbookViewModels,

在52MVCBlog.IRepository程序集下添加IGuestbookRepository,IAdvertisementRepository,

在52MVCBlog.Repository程序集下添加GuestbookRepository,AdvertisementRepository

在52MVCBlog.IService程序集下添加IGuestbookServices,IAdvertisementServices,

在52MVCBlog.Service程序集下添加GuestbookServices,AdvertisementServices

3.2实现主页面展示

控制台安装 Install-Package Webdiyer.MvcPager -Version 3.0.1.1

在控制器下的文件夹中创建一个Home控制器,在控制器index下实现查询博客信息代码

  1. using _52MVCBlog.IService;
  2. using _52MVCBlog.Model.Models;
  3. using _52MVCBlog.WebCore;
  4. using System;
  5. using System.Collections.Generic;
  6. using System.Linq;
  7. using System.Web;
  8. using System.Web.Mvc;
  9. using Webdiyer.WebControls.Mvc;
  10. using _52MVCBlog.Common.ToolsHelper;
  11.  
  12. namespace _52MVCBlog.WebUI.Controllers
  13. {
  14. public class HomeController : BaseController
  15. {
  16. IsysUserInfoServices userinfoservice;
  17. IBlogArticleServices BlogArticleServive;
  18. IAdvertisementServices AdvertisementServices;
  19. IGuestbookServices GuestbookServices;
  20.  
  21. public HomeController(IsysUserInfoServices userinfs, IBlogArticleServices BlogArticleServive, IAdvertisementServices AdvertisementServices, IGuestbookServices GuestbookServices)
  22. {
  23. this.userinfoservice = userinfs;
  24. this.BlogArticleServive = BlogArticleServive;
  25. this.AdvertisementServices = AdvertisementServices;
  26. this.GuestbookServices = GuestbookServices;
  27. }
  28. public ActionResult Index(int pageindex = )
  29. {
  30. //获取控制器名称
  31. ViewBag.controllername = RouteData.Values["controller"].ToString().ToLower();
  32.  
  33. int pagesize = ;
  34. //获取发布博文信息
  35. var blogArticleList = BlogArticleServive.QueryWhere(a => true).OrderByDescending(a => a.bCreateTime).ToPagedList(pageindex, pagesize);
  36. foreach (var item in blogArticleList)
  37. {
  38. if (!string.IsNullOrEmpty(item.bcontent))
  39. {
  40. item.bcontent = Tools.ReplaceHtmlTag(item.bcontent);
  41. if (item.bcontent.Length > )
  42. {
  43. item.bcontent = item.bcontent.Substring(, );
  44. }
  45. }
  46.  
  47. }
  48. //获取轮播广告新
  49. ViewBag.adList = AdvertisementServices.QueryOrderBy(a => true, a => a.Createdate, false).ToPagedList(, );
  50. //发布时间排序
  51. ViewBag.blogtimelist = BlogArticleServive.QueryOrderBy(c => true, c => c.bCreateTime, false);
  52. //评论排序
  53. ViewBag.blogtrafficlist = BlogArticleServive.QueryOrderBy(c => true, c => c.btraffic, false);
  54. //留言排序
  55. string sql = @"select a.*,b.btitle from (select blogId,count(1) as counts from Guestbook group by blogId) as a
  56. inner join BlogArticle as b
  57. on
  58. b.bID=a.blogId order by counts desc";
  59.  
  60. ViewBag.blogguestbooklist = GuestbookServices.RunProc<TopgbViewModels>(sql);
  61.  
  62. return View(blogArticleList);
  63. }
  64. }
  65. }

然后创建一个Index视图页面

Index视图页代码

  1. @model PagedList<_52MVCBlog.Model.Models.BlogArticle>
  2. @using Webdiyer.WebControls.Mvc
  3.  
  4. @{
  5. ViewBag.Title = "首页";
  6. }
  7.  
  8. <section id="lunbotu">
  9. <div id="myNiceCarousel" class="carousel slide" data-ride="carousel">
  10. <!-- 圆点指示器 -->
  11. <ol class="carousel-indicators">
  12. <li data-target="#myNiceCarousel" data-slide-to="" class="active"></li>
  13. <li data-target="#myNiceCarousel" data-slide-to=""></li>
  14. <li data-target="#myNiceCarousel" data-slide-to=""></li>
  15. </ol>
  16.  
  17. <!-- 轮播项目 -->
  18. <div class="carousel-inner">
  19. @foreach (var item in ViewBag.adList)
  20. {
  21. if (item == ViewBag.adList[])
  22. {
  23. <div class="item active">
  24. <a href="@item.Url" title="@item.Title" target="_blank">
  25. <img alt="First slide" src="@item.ImgUrl">
  26. </a>
  27. <div class="carousel-caption">
  28. <h3>@item.Title</h3>
  29. </div>
  30. </div>
  31. }
  32. else
  33. {
  34. <div class="item">
  35. <a href="@item.Url" title="@item.Title" target="_blank">
  36. <img alt="Second slide" src="@item.ImgUrl">
  37. </a>
  38.  
  39. <div class="carousel-caption">
  40. <h3>@item.Title</h3>
  41. </div>
  42. </div>
  43. }
  44. }
  45. @*<div class="item active">
  46. <a href="http://www.baidu.com" title="baidu" target="_blank">
  47. <img alt="First slide" src="/upload/20161006/1.jpg">
  48. </a>
  49. <div class="carousel-caption">
  50. <h3>我是第一张幻灯片</h3>
  51. </div>
  52. </div>
  53. <div class="item">
  54. <img alt="Second slide" src="/upload/20161006/2.jpg">
  55. <div class="carousel-caption">
  56. <h3>我是第二张幻灯片</h3>
  57. </div>
  58. </div>
  59. <div class="item">
  60. <img alt="Third slide" src="/upload/20161006/3.jpg">
  61. <div class="carousel-caption">
  62. <h3>我是第三张幻灯片</h3>
  63. </div>
  64. </div>*@
  65. </div>
  66.  
  67. <!-- 项目切换按钮 -->
  68. <a class="left carousel-control" href="#myNiceCarousel" data-slide="prev">
  69. <span class="icon icon-chevron-left"></span>
  70. </a>
  71. <a class="right carousel-control" href="#myNiceCarousel" data-slide="next">
  72. <span class="icon icon-chevron-right"></span>
  73. </a>
  74. </div>
  75. </section>
  76. <section id="boke">
  77. @foreach (var item in Model)
  78. {
  79. <div class="day">
  80. <div class="dayTitle">
  81. <a class="btn btn-primary">@item.bCreateTime.ToString("yyyy年MM月dd日")</a>
  82. </div>
  83. <div class="postTitle">
  84. <a id="" class="postTitle2" href="/blog/Detail/@item.bID">@item.btitle</a>
  85. </div>
  86. <div class="postCon">
  87. <div class="c_b_p_desc">
  88. 摘要:@item.bcontent......
  89. <a href="/blog/Detail/@item.bID" class="btn btn-primary">阅读全文</a>
  90. </div>
  91. </div>
  92. <div class="postDesc">
  93. <p>posted @@ @item.bCreateTime @item.bsubmitter 阅读(@item.btraffic) 评论(@item.bcommentNum) </p>
  94. </div>
  95. </div>
  96. }
  97.  
  98. <footer class="pagination">
  99. @Ajax.Pager(Model, new PagerOptions { PageIndexParameterName = "pageindex", ContainerTagName = "ul", CssClass = "pager", CurrentPagerItemTemplate = "<li class=\"active\"><a href=\"#\">{0}</a></li>", DisabledPagerItemTemplate = "<li class=\"disabled\"><a>{0}</a></li>", PagerItemTemplate = "<li>{0}</li>" }, new MvcAjaxOptions { UpdateTargetId = "boke", OnBegin = "alert('onbegin事件引发')", OnSuccess = "handleSuccess", OnComplete = "function(xhr,status){alert('oncomplete事件引发,Http响应代码:'+xhr.status+',响应内容:'+xhr.statusText+',状态代码:'+status)}", OnFailure = "handleFailure" })
  100. @*@Html.Pager(Model, new PagerOptions { PageIndexParameterName = "pageindex", ContainerTagName = "ul", CssClass = "pager", CurrentPagerItemTemplate = "<li class=\"active\"><a href=\"#\">{0}</a></li>", DisabledPagerItemTemplate = "<li class=\"disabled\"><a>{0}</a></li>", PagerItemTemplate = "<li>{0}</li>" })*@
  101. @*@Html.Pager(Model, new PagerOptions { PageIndexParameterName = "pageindex", CurrentPagerItemTemplate = "<span class=\"current\">{0}</span>", DisabledPagerItemTemplate = "<span class=\"disabled\">{0}</span>", Id = "badoopager" })*@
  102. </footer>
  103. </section>

应用数据库自动迁移后update-database -force调试页面

四、博客系统发布博客功能以及展示功能总结

    这里使用到了的两个插件一个是后台的富文本编辑器;一个是mvc分页插件,具体插件可以去相应的官网查看详细的使用方法,富文本编辑器官网:http://www.wangeditor.com/;mvc分页插件官网:http://www.webdiyer.com/mvcpager/

主要的分布实现是使用到了mvc布局页来实现的,实现页面功能的时候,一般都是先把静态页面做出来,然后在把前台页面移至到项目中,把需要展示数据的地方修改成动态的就可以了。

这里在说明一下我的文件夹设计我在Content文件夹下创建了CSS、fonts、images、JS、lib文件夹,把所有自定和用到的主要UI框架文件分类放在对应的文件夹中,lib文件夹主要放所有的第三方的插件文件,另外还添加了一个upload文件夹主要存放所有上传的文件图片的。

using _52MVCBlog.IService;using _52MVCBlog.Model.Models;using _52MVCBlog.WebCore;using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using Webdiyer.WebControls.Mvc;using _52MVCBlog.Common.ToolsHelper;
namespace _52MVCBlog.WebUI.Controllers{    public class HomeController : BaseController    {        IsysUserInfoServices userinfoservice;        IBlogArticleServices BlogArticleServive;        IAdvertisementServices AdvertisementServices;        IGuestbookServices GuestbookServices;
        public HomeController(IsysUserInfoServices userinfs, IBlogArticleServices BlogArticleServive, IAdvertisementServices AdvertisementServices, IGuestbookServices GuestbookServices)        {            this.userinfoservice = userinfs;            this.BlogArticleServive = BlogArticleServive;            this.AdvertisementServices = AdvertisementServices;            this.GuestbookServices = GuestbookServices;        }        public ActionResult Index(int pageindex = 1)        {            //获取控制器名称            ViewBag.controllername = RouteData.Values["controller"].ToString().ToLower();
            int pagesize = 6;            //获取发布博文信息            var blogArticleList = BlogArticleServive.QueryWhere(a => true).OrderByDescending(a => a.bCreateTime).ToPagedList(pageindex, pagesize);            foreach (var item in blogArticleList)            {                if (!string.IsNullOrEmpty(item.bcontent))                {                    item.bcontent = Tools.ReplaceHtmlTag(item.bcontent);                    if (item.bcontent.Length > 200)                    {                        item.bcontent = item.bcontent.Substring(0, 200);                    }                }
            }            //获取轮播广告新            ViewBag.adList = AdvertisementServices.QueryOrderBy(a => true, a => a.Createdate, false).ToPagedList(1, 3);            //发布时间排序            ViewBag.blogtimelist = BlogArticleServive.QueryOrderBy(c => true, c => c.bCreateTime, false);            //评论排序            ViewBag.blogtrafficlist = BlogArticleServive.QueryOrderBy(c => true, c => c.btraffic, false);            //留言排序            string sql = @"select a.*,b.btitle from (select blogId,count(1) as counts  from Guestbook group by blogId) as ainner join BlogArticle as bonb.bID=a.blogId order by counts desc";
           ViewBag.blogguestbooklist = GuestbookServices.RunProc<TopgbViewModels>(sql);
            return View(blogArticleList);        }    }}

【干货】利用MVC5+EF6搭建博客系统(四)(下)前后台布局实现、发布博客以及展示的更多相关文章

  1. 【干货】利用MVC5+EF6搭建博客系统(四)(上)前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

  2. 【干货】利用MVC5+EF6搭建博客系统(三)添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController

    PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.回顾系统进度以及本章概要 目前博客系统已经数据库创建.以及依赖注入Autofac集成,接下来就是日志和缓存集成,这里日志用的是N ...

  3. 从零开始,搭建博客系统MVC5+EF6搭建框架(4)上,前后台页面布局页面实现,介绍使用的UI框架以及JS组件

    一.博客系统进度回顾以及页面设计 1.1页面设计说明 紧接前面基础基本完成了框架搭建,现在开始设计页面,前台页面设计我是模仿我博客园的风格来设计的,后台是常规的左右布局风格. 1.2前台页面风格 主页 ...

  4. 从零开始,搭建博客系统MVC5+EF6搭建框架(4)下,前后台布局实现、发布博客以及展示。

    一.博客系统进度回顾 目前已经完成了,前台展示,以及后台发布的功能,最近都在做这个,其实我在国庆的时候就可以弄完的,但是每天自己弄,突然最后国庆2天,连电脑都不想碰,所以就一直拖着,上一篇写了前端实现 ...

  5. 【干货】利用MVC5+EF6搭建博客系统(二)测试添加数据、集成Autofac依赖注入

    PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.测试仓储层.业务层是否能实现对数据库表的操作 1.在52MVCBlog.IRepository程序集下创建IsysUserInf ...

  6. 【干货】利用MVC5+EF6搭建博客系统(一)EF Code frist、实现泛型数据仓储以及业务逻辑

    习MVC有一段时间了,决定自己写一套Demo了,写完源码再共享. PS:如果图片模糊,鼠标右击复制图片网址,然后在浏览器中打开即可. 一.框架搭建 二.创建数据库 1.创建一个空的EF code fr ...

  7. 利用MVC5+EF6搭建博客系统

    https://www.cnblogs.com/wyt007/p/7880137.html

  8. 从零开始,搭建博客系统MVC5+EF6搭建框架(1),EF Code frist、实现泛型数据仓储以及业务逻辑

    前言      从上篇30岁找份程序员的工作(伪程序员的独白),文章开始,我说过我要用我自学的技术,来搭建一个博客系统,也希望大家给点意见,另外我很感谢博客园的各位朋友们,对我那篇算是自我阶段总结文章 ...

  9. 从零开始,搭建博客系统MVC5+EF6搭建框架(5),博客详情页、留言、轮播图管理、右侧统计博文

    一.博客系统进度回顾 上一遍博客介绍到,系统已经实现到了发布以及前台布局展示,接下来就是实现一些,详情页,留言.轮播图管理.右侧博文统计信息实现. 二.博客系统详情页实现 2.1先来看看详情页展示的效 ...

随机推荐

  1. 《Linux就该这么学》第十三天课程

    使用Apache服务部署静态网站 原创地址:https://www.linuxprobe.com/chapter-10.html 今天学了Apache,这只是RHCE课程的开始,估计后面越来越难 今天 ...

  2. version control

    what 版本控制最主要的功能就是追踪文件的变更.它将什么时候.什么人更改了文件的什么内容等信息忠实地了已录下来.每一次文件的改变,文件的版本号都将增加.除了记录版本变更外,版本控制的另一个重要功能是 ...

  3. FeatureTools

    featuretools一种自动特征工程的工具.可快速生成较多类型的特征,取得不错的效果. 1.输入:把原始数据转换成featuretools的输入 2. 可以适当调整特征个数,防止训练的模型过拟合 ...

  4. redis学习-string常用命令

    keys * :查询所有的key值 set:为指定键设置对应的值 get:获取指定键的值 mset:一次传入多个键值对 mget:一次获取多个键的值 del:删除指定键 strlen:获取指定键值的长 ...

  5. vue路由独享守卫beforeEnter

    在某个路由中,使用beforeEnter()方法,参数是to,from,next 和全局路由守卫的用法是一样的 例子: import Vue from 'vue' import Router from ...

  6. windows系统中配置多版本anaconda

    1.最好从国内的镜像站下载anaconda,国外那个站实在是太慢了,清华开源软件镜像站(https://mirrors.tuna.tsinghua.edu.cn/help/anaconda/) 2.如 ...

  7. C# WebAPI系列(1)

    WebApi是微软在VS2012 MVC4版本中绑定发行的,WebApi是完全基于Restful标准的框架.RestFul: (英文:Representational State Transfer,简 ...

  8. ANDROID说说对MENU的理解

    ANDROID%E5%88%9D%E5%AD%A6%E4%B9%8B%E7%AE%80%E6%98%93%E8%AE%A1%E7%AE%97%E5%99%A8 Ѿ�����ڴ����㺰ô�

  9. Python之旅Day4 闭包函数 模块及模块倒入

    闭包函数 闭包函数就是在内部函数当中有对外部函数名字的引用 ###代码示例1### def f1(): x =1 def f2(): print(x) return f2 f=f1() f() ### ...

  10. Web browser发展演变

    浏览器是指可以显示网页服务器或者文件系统的HTML文件内容,并让用户与这些文件交互的一种软件.网页浏览器主要通过HTTP协议与网页服务器交互并获取网页,这些网页由URL指定,文件格式通常为HTML.大 ...