一、博客系统进度回顾

上一遍博客介绍到,系统已经实现到了发布以及前台布局展示,接下来就是实现一些,详情页,留言、轮播图管理、右侧博文统计信息实现。

二、博客系统详情页实现

2.1先来看看详情页展示的效果

2.2实现控制器在前台控制器中创建一个Blog的控制器,主要是展示博客分类以及详情页

Action详情页实现:

  1. 1 /// <summary>
  2. 2 /// 详情页
  3. 3 /// </summary>
  4. 4 /// <param name="id"></param>
  5. 5 /// <returns></returns>
  6. 6 public ActionResult Detail(int id)
  7. 7 {
  8. 8 //获取控制器名称
  9. 9 ViewBag.controllername = RouteData.Values["controller"].ToString().ToLower();
  10. 10 var model = BlogArticleServive.getBlogDetails(id);
  11. 11 ViewBag.gblist = GuestbookServices.QueryOrderBy(c => c.blogId == id, c => c.createdate, false).ToPagedList(1, 5);
  12. 12
  13. 13 //发布时间排序
  14. 14 ViewBag.blogtimelist = BlogArticleServive.QueryOrderBy(c => true, c => c.bCreateTime, false);
  15. 15 //评论排序
  16. 16 ViewBag.blogtrafficlist = BlogArticleServive.QueryOrderBy(c => true, c => c.btraffic, false);
  17. 17 //留言排序
  18. 18 string sql = @"select a.*,b.btitle from (select blogId,count(1) as counts from Guestbook group by blogId) as a
  19. 19 inner join BlogArticle as b
  20. 20 on
  21. 21 b.bID=a.blogId order by counts desc";
  22. 22
  23. 23 ViewBag.blogguestbooklist = GuestbookServices.RunProc<TopgbViewModels>(sql);
  24. 24
  25. 25 return View(model);
  26. 26 }

由于展示的内容比实际存储在数据库中的信息多,所以把所有能展示的信息都放在BlogViewModels中,在blog业务逻辑层单独实现了一个包含上一页 下一页,以及摘要赋值的方法。

由于这一部分需要从详情内容中只保留部分文字,所以这里需要对索取的详情信息做处理,由于详情信息是通过富文本编辑来添加的里面包含了很多html代码信息,所以在common程序集中,创建一个工具类,Tools类来存放,辅助的相关方法。

ReplaceHtmlTag方法:

  1. 1 #region 去除富文本中的HTML标签
  2. 2 /// <summary>
  3. 3 /// 去除富文本中的HTML标签
  4. 4 /// </summary>
  5. 5 /// <param name="html"></param>
  6. 6 /// <param name="length"></param>
  7. 7 /// <returns></returns>
  8. 8 public static string ReplaceHtmlTag(string html, int length = 0)
  9. 9 {
  10. 10 string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", "");
  11. 11 strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", "");
  12. 12
  13. 13 if (length > 0 && strText.Length > length)
  14. 14 return strText.Substring(0, length);
  15. 15
  16. 16 return strText;
  17. 17 }
  18. 18 #endregion

然后在获取到多有信息,要处理的地方就是用三元运算符来判断,截取前面的文字部分

2.3详情页视图代码

  1. 1 @model Wchl.WMBlog.Model.VeiwModels.BlogViewModels
  2. 2
  3. 3 @{
  4. 4 ViewBag.Title = "博客详情页";
  5. 5 }
  6. 6 <link href="~/Content/lib/zui/doc.css" rel="stylesheet" />
  7. 7 <section>
  8. 8 <article>
  9. 9 <div spellcheck="false" class="example">
  10. 10 <br>
  11. 11 <ul class="breadcrumb">
  12. 12 <li><i class="icon-location-arrow icon-muted"></i></li>
  13. 13 <li><a href="/home/index">首页</a></li>
  14. 14 <li><a href="/blog/index">博客</a></li>
  15. 15 <li class="active">Data</li>
  16. 16 </ul>
  17. 17 <hr>
  18. 18 <article class="article">
  19. 19 <header>
  20. 20 <h1 class="text-center">@Model.btitle</h1>
  21. 21 <dl class="dl-inline">
  22. 22 <dt>发布时间:</dt>
  23. 23 <dd>@Model.bCreateTime</dd>
  24. 24 <dt>作者:</dt>
  25. 25 <dd>@Model.bsubmitter</dd>
  26. 26 <dt></dt>
  27. 27 <dd class="pull-right"><span class="label label-success">新</span> <span class="label label-warning">火爆</span> <span class="label label-info">原创</span> <span class="label label-danger"><i class="icon-eye-open"></i> @Model.btraffic</span></dd>
  28. 28 </dl>
  29. 29 <section class="abstract">
  30. 30 <p><strong>摘要:</strong>@Model.digest</p>
  31. 31 </section>
  32. 32 </header>
  33. 33 <section class="article-content">
  34. 34 @Html.Raw(Model.bcontent)
  35. 35 </section>
  36. 36 <footer>
  37. 37 <p class="pull-right text-muted">
  38. 38 发布时间:@Model.bCreateTime.ToString("yyyy年MM月dd日 HH:mm:ss") &nbsp;点击数:@Model.btraffic
  39. 39 </p>
  40. 40 <p class="text-important">本文版权所有归<a href="###">@Model.bsubmitter</a></p>
  41. 41 <ul class="pager pager-justify">
  42. 42 @if (Model.previous == null)
  43. 43 {
  44. 44 <li class="previous disabled"><a href="#" title=""><i class="icon-arrow-left"></i> 上一篇: </a></li>
  45. 45 }
  46. 46 else
  47. 47 {
  48. 48 <li class="previous"><a href="/blog/Detail/@Model.previousID " title="@Model.previous"><i class="icon-arrow-left"></i> 上一篇: @Model.previous.Substring(0, 5) </a></li>
  49. 49 }
  50. 50 @if (Model.next == null)
  51. 51 {
  52. 52 <li class="next disabled"><a href="#">下一篇: <i class="icon-arrow-right"></i></a></li>
  53. 53 }
  54. 54 else
  55. 55 {
  56. 56 <li class="next"><a href="/blog/Detail/@Model.nextID " title="=@Model.next">下一篇:@Model.next.Substring(0, 5) <i class="icon-arrow-right"></i></a></li>
  57. 57 }
  58. 58
  59. 59
  60. 60 </ul>
  61. 61 </footer>
  62. 62 </article>
  63. 63 </div>
  64. 64 </article>
  65. 65 <div id="comment">
  66. 66 @Html.Partial("_GuestbookPage")
  67. 67 </div>
  68. 68
  69. 69 </section>
  70. 70 @section scripts
  71. 71 {
  72. 72 <script src="~/Content/lib/laypage/laypage.js"></script>
  73. 73 <script type="text/javascript">
  74. 74 var blogid;
  75. 75 var curr;
  76. 76 $(function () {
  77. 77 $("#blogId").val(@Model.bID);
  78. 78 //运行分页
  79. 79 blogid = $("#blogId").val();
  80. 80 guestbookpage(curr,blogid);
  81. 81 })
  82. 82
  83. 83 function su(data) {
  84. 84 $("#comment").html(data);
  85. 85 $("#blogId").val(@Model.bID);
  86. 86 //setTimeout(function () {
  87. 87 // if (document.getElementById('textcenter') != null) {
  88. 88 // //运行分页
  89. 89 // guestbookpage(1, blogid);
  90. 90 // }
  91. 91 //}, 3000);
  92. 92 if (document.getElementById('textcenter') != null) {
  93. 93 //运行分页
  94. 94 guestbookpage(1, blogid);
  95. 95 }
  96. 96
  97. 97
  98. 98
  99. 99 }
  100. 100
  101. 101 //以下将以jquery.ajax为例,演示一个异步分页
  102. 102 function guestbookpage(curr,blogid) {
  103. 103 $.getJSON('/blog/getGuestbook', {
  104. 104 page: curr || 1,
  105. 105 blogId: blogid//向服务端传的参数,此处只是演示
  106. 106 }, function (res) {
  107. 107 //此处仅仅是为了演示变化的内容
  108. 108 $("#comments-list").html(res.content);
  109. 109 //显示分页
  110. 110 laypage({
  111. 111 cont: document.getElementById('textcenter'), //容器。值支持id名、原生dom对象,jquery对象。【如该容器为】:<div id="page1"></div>
  112. 112 pages: res.pages, //通过后台拿到的总页数
  113. 113 curr: curr || 1, //当前页
  114. 114 jump: function (obj, first) { //触发分页后的回调
  115. 115 if (!first) { //点击跳页触发函数自身,并传递当前页:obj.curr
  116. 116 curr = obj.curr;
  117. 117 guestbookpage(curr, blogid);
  118. 118 } else {
  119. 119 curr = first;
  120. 120 guestbookpage(curr, blogid);
  121. 121 }
  122. 122
  123. 123 }
  124. 124 });
  125. 125 });
  126. 126 };
  127. 127 </script>
  128. 128 }
  129. 129

这里博客的详情页也是通过布局页来实现的。

三、博客系统详情页留言实现

3.1留言展示页面效果

先要创建一个类在数据库中创建一个表:

Guestbook类

  1. 1 namespace Wchl.WMBlog.Model.Models
  2. 2 {
  3. 3 public class Guestbook
  4. 4 {
  5. 5
  6. 6 /// <summary>留言表
  7. 7 ///
  8. 8 /// </summary>
  9. 9 public int id { get; set; }
  10. 10
  11. 11 /// <summary>博客ID
  12. 12 ///
  13. 13 /// </summary>
  14. 14 public int? blogId { get; set; }
  15. 15 /// <summary>创建时间
  16. 16 ///
  17. 17 /// </summary>
  18. 18 public DateTime createdate { get; set; }
  19. 19 public string username { get; set; }
  20. 20
  21. 21 /// <summary>手机
  22. 22 ///
  23. 23 /// </summary>
  24. 24 public string phone { get; set; }
  25. 25 /// <summary>qq
  26. 26 ///
  27. 27 /// </summary>
  28. 28 public string QQ { get; set; }
  29. 29
  30. 30 /// <summary>留言内容
  31. 31 ///
  32. 32 /// </summary>
  33. 33 public string body { get; set; }
  34. 34 /// <summary>ip地址
  35. 35 ///
  36. 36 /// </summary>
  37. 37 public string ip { get; set; }
  38. 38
  39. 39 /// <summary>是否显示在前台,0否1是
  40. 40 ///
  41. 41 /// </summary>
  42. 42 public bool isshow { get; set; }
  43. 43
  44. 44 public BlogArticle blogarticle { get; set; }
  45. 45 }
  46. 46 }

GuestbookViewModels展示类:

  1. 1 namespace Wchl.WMBlog.Model.VeiwModels
  2. 2 {
  3. 3 /// <summary>
  4. 4 /// 留言信息展示类
  5. 5 /// </summary>
  6. 6 public class GuestbookViewModels
  7. 7 {
  8. 8 /// <summary>留言表
  9. 9 ///
  10. 10 /// </summary>
  11. 11 public int id { get; set; }
  12. 12
  13. 13 /// <summary>博客ID
  14. 14 ///
  15. 15 /// </summary>
  16. 16 public int? blogId { get; set; }
  17. 17 /// <summary>创建时间
  18. 18 ///
  19. 19 /// </summary>
  20. 20 public DateTime createdate { get; set; }
  21. 21 public string username { get; set; }
  22. 22
  23. 23 /// <summary>手机
  24. 24 ///
  25. 25 /// </summary>
  26. 26 public string phone { get; set; }
  27. 27 /// <summary>qq
  28. 28 ///
  29. 29 /// </summary>
  30. 30 public string QQ { get; set; }
  31. 31
  32. 32 /// <summary>留言内容
  33. 33 ///
  34. 34 /// </summary>
  35. 35 public string body { get; set; }
  36. 36 /// <summary>ip地址
  37. 37 ///
  38. 38 /// </summary>
  39. 39 public string ip { get; set; }
  40. 40
  41. 41 /// <summary>是否显示在前台,0否1是
  42. 42 ///
  43. 43 /// </summary>
  44. 44 public bool isshow { get; set; }
  45. 45
  46. 46 public BlogArticle blogarticle { get; set; }
  47. 47 }
  48. 48 }

GuestbookMap字段约束:

  1. 1
  2. 2 namespace Wchl.WMBlog.Model.Maps
  3. 3 {
  4. 4 public class GuestbookMap: EntityTypeConfiguration<Guestbook>
  5. 5 {
  6. 6 public GuestbookMap() {
  7. 7 this.HasKey(p => p.id);
  8. 8 //设置外键
  9. 9 this.HasRequired(p => p.blogarticle).WithMany().HasForeignKey(p => p.blogId);
  10. 10 }
  11. 11 }
  12. 12 }

接下来就是创建相应的仓储接口、实现,服务接口、实现,这里就不一一介绍了,跟上一篇实现博客类的是一样的。

我在实现这个功能的时候,想使用ajax来提交:

这里我把所有留言的内容放在一个部分视图页

_GuestbookPage代码:

  1. 1 <article>
  2. 2 <div spellcheck="false" class="example">
  3. 3 <div class="comments">
  4. 4 <header>
  5. 5 <div class="pull-right"><a href="#commentReplyForm2" class="btn btn-primary"><i class="icon-comment-alt"></i> 发表评论</a></div>
  6. 6 <h3>所有评论</h3>
  7. 7 </header>
  8. 8 <section class="comments-list" id="comments-list">
  9. 9 @{ if (ViewBag.gblist != null)
  10. 10 {
  11. 11 foreach (var list in ViewBag.gblist)
  12. 12 {
  13. 13 <div class="comment">
  14. 14 <a href="###" class="avatar">
  15. 15 <i class="icon-user icon-2x"></i>
  16. 16 </a>
  17. 17 <div class="content">
  18. 18 <div class="pull-right text-muted">@list.createdate</div>
  19. 19 <div><a href="###"><strong>@list.username</strong></a></div>
  20. 20 <div class="text">@list.body</div>
  21. 21 <div class="actions">
  22. 22 <a href="##">回复</a>
  23. 23 </div>
  24. 24 </div>
  25. 25 </div>
  26. 26 }
  27. 27 }
  28. 28
  29. 29 }
  30. 30 </section>
  31. 31 <br />
  32. 32 <div class="text-center" id="textcenter">
  33. 33
  34. 34 </div>
  35. 35 <footer>
  36. 36 <div class="reply-form" id="commentReplyForm2">
  37. 37 <a href="###" class="avatar"><i class="icon-user icon-2x"></i></a>
  38. 38 @using (Ajax.BeginForm("addGuestbook", "Blog", new AjaxOptions()
  39. 39 {
  40. 40 HttpMethod = "post",
  41. 41 OnSuccess="su"
  42. 42
  43. 43 }, new { @class = "form-horizontal" }))
  44. 44 {
  45. 45 <input type="hidden" id="blogId" name="blogId" value=""/>
  46. 46 <div class="form-group col-md-4 form-inline">
  47. 47 <label for="username" class="col-xs-3">昵称</label>
  48. 48 <div>
  49. 49 <input type="text" class="form-control" name="username" id="username" placeholder="昵称">
  50. 50 </div>
  51. 51 </div>
  52. 52 <div class="form-group col-md-4 form-inline">
  53. 53 <label for="phone" class="col-xs-3">手机</label>
  54. 54 <div>
  55. 55 <input type="text" class="form-control" name="phone" id="phone" placeholder="手机">
  56. 56 </div>
  57. 57 </div>
  58. 58 <div class="form-group col-md-4 form-inline">
  59. 59 <label for="QQ" class="col-xs-3">Q Q</label>
  60. 60 <div>
  61. 61 <input type="text" class="form-control" name="QQ" id="QQ" placeholder="Q Q">
  62. 62 </div>
  63. 63 </div>
  64. 64 <div class="form-group"></div>
  65. 65 <div class="form-group">
  66. 66 <textarea class="form-control new-comment-text" id="body" name="body" rows="4" placeholder="撰写留言..."></textarea>
  67. 67 </div>
  68. 68 <div class="form-group comment-user">
  69. 69 <div class="row">
  70. 70 <div class="col-md-2 col-md-offset-10"><button type="submit" class="btn btn-block btn-primary " value="提交">提交</button></div>
  71. 71 </div>
  72. 72 </div>
  73. 73 }
  74. 74 </div>
  75. 75 </footer>
  76. 76 </div>
  77. 77 </div>
  78. 78 </article>
  79. 79

其中分为两部分,一部分是输入留言,一部分是展示信息。

留言提交的表单如下:

在blog控制器中实现添加数据方法:

  1. 1 /// <summary>
  2. 2 ///提交评论
  3. 3 /// </summary>
  4. 4 /// <param name="model"></param>
  5. 5 /// <returns></returns>
  6. 6 [HttpPost]
  7. 7 public ActionResult addGuestbook(GuestbookViewModels model)
  8. 8 {
  9. 9 model.createdate = DateTime.Now;
  10. 10 model.ip = Request.UserHostAddress;
  11. 11 //AutoMapper自动映射
  12. 12 Mapper.Initialize(cfg => cfg.CreateMap<GuestbookViewModels, Guestbook > ());
  13. 13 Guestbook models = Mapper.Map< GuestbookViewModels, Guestbook> (model);
  14. 14 BlogArticle blogArticle = BlogArticleServive.QueryWhere(a => a.bID == model.blogId).FirstOrDefault();
  15. 15 blogArticle.bcommentNum += 1;
  16. 16 BlogArticleServive.SaverChanges();
  17. 17 GuestbookServices.Add(models);
  18. 18 GuestbookServices.SaverChanges();
  19. 19 ViewBag.gblist = GuestbookServices.QueryOrderBy(c => c.blogId == model.blogId, c => c.createdate, false).ToPagedList(1, 5);
  20. 20 return PartialView("_GuestbookPage");
  21. 21 }

执行成功之后就把信息加载到分页信息的位置。

3.2添加实现之后就是展示数据,展示数据使用的是一个js分页插件laypage.js

在mvc的视图中只能在页面有一个model类,所以就只能使用ViewBag.gblist来传值了,本来这个打算用mvcpager插件,结果发现不行,就只能使用js来分页,实现如下:

后台blog控制器下,实现分页,然后拼接数据:

  1. 1 /// <summary>
  2. 2 /// js分页实现
  3. 3 /// </summary>
  4. 4 /// <param name="page"></param>
  5. 5 /// <param name="blogId"></param>
  6. 6 /// <returns></returns>
  7. 7 public ActionResult getGuestbook(int page,int blogId)
  8. 8 {
  9. 9 StringBuilder sb = new StringBuilder();
  10. 10 int pages = 0;
  11. 11 var modelsLists = GuestbookServices.QueryByPage(page, 5,out pages, c => c.blogId == blogId, c => c.createdate, false);
  12. 12 foreach (var item in modelsLists)
  13. 13 {
  14. 14 sb.AppendFormat(@"<div class='comment'>
  15. 15 <a href = '###' class='avatar'>
  16. 16 <i class='icon-user icon-2x'></i>
  17. 17 </a>
  18. 18 <div class='content'>
  19. 19 <div class='pull-right text-muted'>{0}</div>
  20. 20 <div><a href = '###' ><strong > {1}</strong ></a ></div>
  21. 21 <div class='text'>{2}</div>
  22. 22 <div class='actions'>
  23. 23 <a href = '##' > 回复 </a>
  24. 24 </div >
  25. 25 </div >
  26. 26 </div >",item.createdate,item.username,item.body);
  27. 27 }
  28. 28 if (pages % 5 == 0)
  29. 29 {
  30. 30 pages = pages / 5;
  31. 31 }
  32. 32 else
  33. 33 {
  34. 34 pages = (pages / 5)+1;
  35. 35 }
  36. 36
  37. 37
  38. 38 return Json(new {
  39. 39 content = sb.ToString(),
  40. 40 pages= pages
  41. 41 });
  42. 42 }

在详情页中直接调用就可以了实现分页了

四、博客系统广告轮播图管理实现

4.1实现效果这里的轮播图使用的是zui中组件来实现的,

4.2主页轮播图视图中的代码实现

4.3轮播图管理后台页面实现展示

这里上传图片使用的是百度的上传控件

视图页代码实现:

  1. 1
  2. 2 @{
  3. 3 ViewBag.Title = "广告管理";
  4. 4 }
  5. 5 @section stylesheet{
  6. 6 <link href="~/Content/CSS/blogArticleStyle.css" rel="stylesheet" />
  7. 7 <link href="~/Content/lib/DataTables/css/jquery.dataTables.css" rel="stylesheet" />
  8. 8 <link href="~/Content/lib/DataTables/css/dataTables.bootstrap.css" rel="stylesheet" />
  9. 9 <link href="~/Content/lib/webuploader/dist/webuploader.css" rel="stylesheet" />
  10. 10 <style type="text/css">
  11. 11 .uploader-list {
  12. 12 width: 100%;
  13. 13 overflow: hidden;
  14. 14 }
  15. 15
  16. 16 .file-item {
  17. 17 float: left;
  18. 18 position: relative;
  19. 19 margin: 0 20px 20px 0;
  20. 20 padding: 4px;
  21. 21 }
  22. 22
  23. 23 .file-item .info {
  24. 24 position: absolute;
  25. 25 left: 4px;
  26. 26 bottom: 4px;
  27. 27 right: 4px;
  28. 28 height: 20px;
  29. 29 line-height: 20px;
  30. 30 text-indent: 5px;
  31. 31 background: rgba(0, 0, 0, 0.6);
  32. 32 color: white;
  33. 33 overflow: hidden;
  34. 34 white-space: nowrap;
  35. 35 text-overflow: ellipsis;
  36. 36 font-size: 12px;
  37. 37 z-index: 10;
  38. 38 }
  39. 39
  40. 40 .file-item .error {
  41. 41 position: absolute;
  42. 42 top: 4px;
  43. 43 left: 4px;
  44. 44 right: 4px;
  45. 45 background: red;
  46. 46 color: white;
  47. 47 text-align: center;
  48. 48 height: 20px;
  49. 49 font-size: 14px;
  50. 50 line-height: 23px;
  51. 51 }
  52. 52
  53. 53 .upload-state-done:after {
  54. 54 content: "\f00c";
  55. 55 font-family: FontAwesome;
  56. 56 font-style: normal;
  57. 57 font-weight: normal;
  58. 58 line-height: 1;
  59. 59 -webkit-font-smoothing: antialiased;
  60. 60 -moz-osx-font-smoothing: grayscale;
  61. 61 font-size: 32px;
  62. 62 position: absolute;
  63. 63 bottom: 0;
  64. 64 right: 4px;
  65. 65 color: #4cae4c;
  66. 66 z-index: 99;
  67. 67 }
  68. 68
  69. 69 .thumbnail {
  70. 70 }
  71. 71 /*表格信息对齐重写*/
  72. 72 .dataTables_wrapper .dataTables_length {
  73. 73 float: left;
  74. 74 margin-left: 15px;
  75. 75 margin-top: 5px;
  76. 76 }
  77. 77 </style>
  78. 78 }
  79. 79
  80. 80 @*<link href="~/Content/CSS/userStyle.css" rel="stylesheet" />*@
  81. 81 <script src="~/Content/lib/DataTables/js/jquery.dataTables.js"></script>
  82. 82 <script src="~/Content/lib/DataTables/js/dataTables.bootstrap.js"></script>
  83. 83 <script src="~/Content/lib/webuploader/dist/webuploader.js"></script>
  84. 84 <script type="text/javascript">
  85. 85 var table;
  86. 86 // 图片上传demo
  87. 87 $(function () {
  88. 88 //百度上传方法
  89. 89 baiduuploader();
  90. 90 //创建表格
  91. 91 creatabel();
  92. 92 });
  93. 93 //初始化表格
  94. 94 function creatabel() {
  95. 95 table = $('#adtabel').DataTable({
  96. 96 "processing": true,
  97. 97 "serverSide": true,
  98. 98 //"paging": true,
  99. 99 "scrollY": 366,
  100. 100 "ajax": {
  101. 101 url: '@Url.Action("getData", "Advertisement")'
  102. 102 //"dataType": "json"
  103. 103 },
  104. 104 // "pagingType": "full_numbers",
  105. 105 // "sLoadingRecords": "正在加载数据...",
  106. 106 // "sZeroRecords": "暂无数据",
  107. 107 //"stateSave": true,
  108. 108 "searching": false,
  109. 109 "aaSorting": [[1, "desc"]],//默认第几个排序
  110. 110 "dom": 'rt<"bottom"iflp><"clear">',
  111. 111 "columns": [
  112. 112 {
  113. 113 "data": "count",
  114. 114 "width": "28px",
  115. 115 },
  116. 116 {
  117. 117 "data": "imgUrl",
  118. 118 "width": "60px",
  119. 119 render: function (data, type, row, meta) {
  120. 120 //这里是主题 把url变成超链接、把图片路径显示为图片
  121. 121 //return "<a href='" + data + "'>" + data + "</a>";
  122. 122 return "<img src='" + data + "' style='width:50px;height:50px' />";
  123. 123 }
  124. 124 },
  125. 125 { "data": "title" },
  126. 126 { "data": "url" },
  127. 127 { "data": "createdate" },
  128. 128 { "data": "remark" },
  129. 129 {
  130. 130 data: null
  131. 131 }
  132. 132 ],
  133. 133 "columnDefs": [
  134. 134 {
  135. 135 // 指定第一列,从0开始,0表示第一列,1表示第二列……
  136. 136 targets: -1,
  137. 137 "width": "100px",
  138. 138 render: function (data, type, row, meta) {
  139. 139 return '<a type="button" class="btn btn-danger" href="#" onclick="del(\'' + row.id + '\')" ><i class="icon icon-trash"></i>删除</a>'
  140. 140 }
  141. 141 }
  142. 142 ],
  143. 143 "language": {
  144. 144 "processing": "玩命加载中...",
  145. 145 "lengthMenu": "显示 _MENU_ 项结果",
  146. 146 "zeroRecords": "没有匹配结果",
  147. 147 "info": "显示第 _START_ 至 _END_ 项结果,共 _TOTAL_ 项",
  148. 148 "infoEmpty": "显示第 0 至 0 项结果,共 0 项",
  149. 149 "infoFiltered": "(由 _MAX_ 项结果过滤)",
  150. 150 "infoPostFix": "",
  151. 151 "url": "",
  152. 152 "paginate": {
  153. 153 "first": "首页",
  154. 154 "previous": "上一页",
  155. 155 "next": "下一页",
  156. 156 "last": "末页"
  157. 157 }
  158. 158 }
  159. 159 });
  160. 160 };
  161. 161
  162. 162 //删除轮播数据
  163. 163 function del(adid) {
  164. 164 if (confirm("是否确认删除?"))
  165. 165 {
  166. 166 $.post('@Url.Action("del", "Advertisement")', { id: adid },function(ajaxobj){
  167. 167 if(ajaxobj.status=="0")
  168. 168 {
  169. 169 //如果后台删除成功,则刷新表格,并提示用户删除成功
  170. 170 //保留分页信息
  171. 171 table.ajax.reload(null,false);
  172. 172 alert("删除成功");
  173. 173 }
  174. 174 })
  175. 175 }
  176. 176 }
  177. 177
  178. 178 //百度上传
  179. 179 function baiduuploader() {
  180. 180 var $ = jQuery,
  181. 181 $list = $('#fileList'),
  182. 182 // 优化retina, 在retina下这个值是2
  183. 183 ratio = window.devicePixelRatio || 1,
  184. 184
  185. 185 // 缩略图大小
  186. 186 thumbnailWidth = 80 * ratio,
  187. 187 thumbnailHeight = 80 * ratio,
  188. 188
  189. 189 // Web Uploader实例
  190. 190 uploader;
  191. 191
  192. 192 // 初始化Web Uploader
  193. 193 uploader = WebUploader.create({
  194. 194
  195. 195 // 自动上传。
  196. 196 auto: true,
  197. 197
  198. 198 // swf文件路径
  199. 199 swf: '/Content/lib/webuploader/dist/Uploader.swf',
  200. 200
  201. 201 // 文件接收服务端。
  202. 202 server: '@Url.Action("UpLoadProcess", "Advertisement")',
  203. 203
  204. 204 // 选择文件的按钮。可选。
  205. 205 // 内部根据当前运行是创建,可能是input元素,也可能是flash.
  206. 206 pick: '#filePicker',
  207. 207
  208. 208 // 只允许选择文件,可选。
  209. 209 accept: {
  210. 210 title: 'Images',
  211. 211 extensions: 'gif,jpg,jpeg,bmp,png',
  212. 212 mimeTypes: 'image/*'
  213. 213 }
  214. 214 });
  215. 215
  216. 216 // 当有文件添加进来的时候
  217. 217 uploader.on('fileQueued', function (file) {
  218. 218 var $li = $(
  219. 219 '<div id="' + file.id + '" class="file-item thumbnail">' +
  220. 220 '<img>' +
  221. 221 '<div class="info">' + file.name + '</div>' +
  222. 222 '</div>'
  223. 223 ),
  224. 224 $img = $li.find('img');
  225. 225
  226. 226 $list.append($li);
  227. 227
  228. 228 // 创建缩略图
  229. 229 uploader.makeThumb(file, function (error, src) {
  230. 230 if (error) {
  231. 231 $img.replaceWith('<span>不能预览</span>');
  232. 232 return;
  233. 233 }
  234. 234
  235. 235 $img.attr('src', src);
  236. 236 }, thumbnailWidth, thumbnailHeight);
  237. 237 });
  238. 238
  239. 239 // 文件上传过程中创建进度条实时显示。
  240. 240 uploader.on('uploadProgress', function (file, percentage) {
  241. 241 var $li = $('#' + file.id),
  242. 242 $percent = $li.find('.progress span');
  243. 243
  244. 244 // 避免重复创建
  245. 245 if (!$percent.length) {
  246. 246 $percent = $('<p class="progress"><span></span></p>')
  247. 247 .appendTo($li)
  248. 248 .find('span');
  249. 249 }
  250. 250
  251. 251 $percent.css('width', percentage * 100 + '%');
  252. 252 });
  253. 253
  254. 254 // 文件上传成功,给item添加成功class, 用样式标记上传成功。
  255. 255 uploader.on('uploadSuccess', function (file, response) {
  256. 256 $('#' + file.id).addClass('upload-state-done');
  257. 257 //alert(response.filePath);
  258. 258 $('#ImgUrl').val(response.filePath);
  259. 259 });
  260. 260
  261. 261 // 文件上传失败,现实上传出错。
  262. 262 uploader.on('uploadError', function (file) {
  263. 263 var $li = $('#' + file.id),
  264. 264 $error = $li.find('div.error');
  265. 265
  266. 266 // 避免重复创建
  267. 267 if (!$error.length) {
  268. 268 $error = $('<div class="error"></div>').appendTo($li);
  269. 269 }
  270. 270
  271. 271 $error.text('上传失败');
  272. 272 });
  273. 273
  274. 274 // 完成上传完了,成功或者失败,先删除进度条。
  275. 275 uploader.on('uploadComplete', function (file) {
  276. 276 $('#' + file.id).find('.progress').remove();
  277. 277 });
  278. 278 };
  279. 279 //上传轮播信息成功之后调用
  280. 280 function afterSu(ajaxobj) {
  281. 281 if (ajaxobj.status == "0") {
  282. 282 alert("上传成功!");
  283. 283 window.location.reload();
  284. 284 } else if (ajaxobj.status == "1") {
  285. 285 alert("上传失败!");
  286. 286 window.location.reload();
  287. 287 }
  288. 288 }
  289. 289 </script>
  290. 290
  291. 291 <!-- head star -->
  292. 292 <div class="tnav row border-bottom white-bg page-heading">
  293. 293 <div class="col-sm-4">
  294. 294 <h2 class="fl">博客后台</h2>
  295. 295 <ol class="breadcrumb fl">
  296. 296 <li><a href="/admin/Home">广告管理</a></li>
  297. 297 <li><strong>轮播图管理</strong></li>
  298. 298 </ol>
  299. 299 </div>
  300. 300 </div>
  301. 301 <!-- head end -->
  302. 302
  303. 303 <div class="example scrollbar-hover" style="max-height: 600px; overflow: scroll;">
  304. 304 <!--table star-->
  305. 305 <table id="adtabel" class="table table-striped table-bordered table-hover dataTables-example dataTable" cellspacing="0">
  306. 306 <thead>
  307. 307 <tr>
  308. 308 <th>编号</th>
  309. 309 <th>图片</th>
  310. 310 <th>标题</th>
  311. 311 <th>链接</th>
  312. 312 <th>创建时间</th>
  313. 313 <th>备注</th>
  314. 314 <th>操作</th>
  315. 315 </tr>
  316. 316 </thead>
  317. 317 <!-- tbody是必须的 -->
  318. 318
  319. 319 </table>
  320. 320 <!--table end-->
  321. 321 <hr />
  322. 322 <!--form star-->
  323. 323 @using (Ajax.BeginForm("add", "Advertisement", new AjaxOptions()
  324. 324 {
  325. 325 HttpMethod = "post",
  326. 326 OnSuccess = "afterSu"
  327. 327 }, new { @class = "form-horizontal" }))
  328. 328 {
  329. 329 <input type="hidden" id="ImgUrl" name="ImgUrl" value="" />
  330. 330 <div class="form-group">
  331. 331 <div class="form-group">
  332. 332 <label for="Title" class="col-sm-2">标题:</label>
  333. 333 <div class="col-md-4 col-sm-10">
  334. 334 <input type="text" class="form-control" id="Title" name="Title" placeholder="标题">
  335. 335 </div>
  336. 336 </div>
  337. 337 <div class="form-group">
  338. 338 <label for="Url" class="col-sm-2">链接:</label>
  339. 339 <div class="col-md-4 col-sm-10">
  340. 340 <input type="text" class="form-control" name="Url" id="Url" placeholder="http://">
  341. 341 </div>
  342. 342 </div>
  343. 343 <div class="form-group">
  344. 344 <label for="Remark" class="col-sm-2">备注:</label>
  345. 345 <div class="col-md-4 col-sm-10">
  346. 346 <textarea rows="2" type="text" class="form-control" name="Remark" id="Remark" placeholder="说明"></textarea>
  347. 347 </div>
  348. 348 </div>
  349. 349 </div>
  350. 350 <div class="form-group">
  351. 351 <label for="exampleInputPassword4" class="col-sm-2">上传图片:</label>
  352. 352 <div class="col-md-10 col-sm-10">
  353. 353 <!--dom结构部分-->
  354. 354 <div id="uploader-demo">
  355. 355 <!--用来存放item-->
  356. 356 <div id="fileList" class="uploader-list"></div>
  357. 357 <div id="filePicker">选择图片</div>
  358. 358 </div>
  359. 359 </div>
  360. 360 </div>
  361. 361 <div class="form-group">
  362. 362 <div class="col-sm-offset-2 col-sm-10">
  363. 363 <button type="submit" class="btn btn-info">提交</button>
  364. 364 </div>
  365. 365 </div>
  366. 366 }
  367. 367 <!--form end-->
  368. 368 </div>
  369. 369
  370. 370
  371. 371

控制器实现后台代码

  1. 1 namespace Wchl.WMBlog.WebUI.Areas.admin.Controllers
  2. 2 {
  3. 3 public class AdvertisementController : BaseController
  4. 4 {
  5. 5 IAdvertisementServices AdvertisementServices;
  6. 6 public AdvertisementController(IAdvertisementServices AdvertisementServices)
  7. 7 {
  8. 8 this.AdvertisementServices = AdvertisementServices;
  9. 9 }
  10. 10
  11. 11 // GET: admin/Advertisement
  12. 12 public ActionResult Index()
  13. 13 {
  14. 14 return View();
  15. 15 }
  16. 16
  17. 17 /// <summary>
  18. 18 /// 获取广告信息
  19. 19 /// </summary>
  20. 20 /// <returns></returns>
  21. 21 public ActionResult getData()
  22. 22 {
  23. 23 int pageIndex = Request["start"] != null ? int.Parse(Request["start"]) : 1;
  24. 24 int pageSize = Request["length"] != null ? int.Parse(Request["length"]) : 5;
  25. 25 int draw = Request["draw"] != null ? int.Parse(Request["draw"]) : 1;
  26. 26 int totalCount;
  27. 27 int count = 0;
  28. 28 var adInfoList = AdvertisementServices.QueryByBeginPage(pageIndex, pageSize, out totalCount, r =>true , r => r.Createdate, false);
  29. 29 var temp = from u in adInfoList
  30. 30 select new { count= count+=1, ID = u.Id, Title = u.Title, ImgUrl = u.ImgUrl, Createdate = u.Createdate,url=u.Url, Remark = u.Remark };
  31. 31 return Json(new {
  32. 32 data = temp.ToList(),
  33. 33 draw = draw,
  34. 34 recordsTotal = totalCount,
  35. 35 recordsFiltered = totalCount
  36. 36 },JsonRequestBehavior.AllowGet);
  37. 37 }
  38. 38
  39. 39 /// <summary>
  40. 40 /// 删除广告
  41. 41 /// </summary>
  42. 42 /// <param name="id"></param>
  43. 43 /// <returns></returns>
  44. 44 [HttpPost]
  45. 45 public ActionResult del(int id)
  46. 46 {
  47. 47 Advertisement model = new Advertisement() {Id=id };
  48. 48 AdvertisementServices.Delete(model, false);
  49. 49 AdvertisementServices.SaverChanges();
  50. 50 return Json(new { status = "0" },JsonRequestBehavior.AllowGet);
  51. 51 }
  52. 52
  53. 53 /// <summary>
  54. 54 /// 添加广告信息
  55. 55 /// </summary>
  56. 56 /// <returns></returns>
  57. 57 [HttpPost]
  58. 58 public ActionResult Add(AdvertisementViewModels model)
  59. 59 {
  60. 60 model.Createdate = DateTime.Now;
  61. 61 //AutoMapper自动映射
  62. 62 Mapper.Initialize(cfg => cfg.CreateMap<AdvertisementViewModels, Advertisement>());
  63. 63 Advertisement models = Mapper.Map<AdvertisementViewModels, Advertisement>(model);
  64. 64 AdvertisementServices.Add(models);
  65. 65 AdvertisementServices.SaverChanges();
  66. 66 return Json(new { status="0" },JsonRequestBehavior.AllowGet);
  67. 67 }
  68. 68
  69. 69 /// <summary>
  70. 70 /// 百度上传图片
  71. 71 /// </summary>
  72. 72 /// <param name="id">百度插件自定义对图片的命名id</param>
  73. 73 /// <param name="name">图片名称</param>
  74. 74 /// <param name="type">图片类型</param>
  75. 75 /// <param name="lastModifiedDate">图片本身的修改时间</param>
  76. 76 /// <param name="size">图片大小</param>
  77. 77 /// <param name="file">文件流</param>
  78. 78 /// <returns></returns>
  79. 79 public ActionResult UpLoadProcess(string id, string name, string type, string lastModifiedDate, int size, HttpPostedFileBase file)
  80. 80 {
  81. 81 string filePathName = string.Empty;
  82. 82
  83. 83 string localPath = Server.MapPath("/upload/");
  84. 84 if (Request.Files.Count == 0)
  85. 85 {
  86. 86 return Json(new { jsonrpc = 2.0, error = new { code = 102, message = "保存失败" }, id = "id" });
  87. 87 }
  88. 88
  89. 89 string ex = Path.GetExtension(file.FileName);
  90. 90 filePathName = Guid.NewGuid().ToString("N") + ex;
  91. 91
  92. 92 string datedir = DateTime.Now.ToString("yyyyMMdd");
  93. 93 if (!Directory.Exists(localPath + datedir))
  94. 94 {
  95. 95 Directory.CreateDirectory(localPath + datedir);
  96. 96 }
  97. 97 string path = localPath + datedir;
  98. 98 try
  99. 99 {
  100. 100 file.SaveAs(Path.Combine(path, filePathName));
  101. 101 }
  102. 102 catch (Exception)
  103. 103 {
  104. 104 return Json(new { jsonrpc = 2.0, error = new { code = 103, message = "保存失败" }, id = "id" });
  105. 105 }
  106. 106 return Json(new
  107. 107 {
  108. 108 jsonrpc = "2.0",
  109. 109 id = id,
  110. 110 filePath = "/Upload/"+datedir + "/" + filePathName
  111. 111 });
  112. 112
  113. 113 }
  114. 114 }
  115. 115 }

广告对应的表的类Advertisement:

  1. 1 namespace Wchl.WMBlog.Model.Models
  2. 2 {
  3. 3 public class Advertisement
  4. 4 {
  5. 5 /// <summary>
  6. 6 /// 分类ID
  7. 7 /// </summary>
  8. 8 public int Id { get; set; }
  9. 9 /// <summary>
  10. 10 /// 创建时间
  11. 11 /// </summary>
  12. 12 public DateTime Createdate { get; set; }
  13. 13
  14. 14 /// <summary>
  15. 15 /// 广告图片
  16. 16 /// </summary>
  17. 17 public string ImgUrl { get; set; }
  18. 18
  19. 19 /// <summary>
  20. 20 /// 广告标题
  21. 21 /// </summary>
  22. 22 public string Title { get; set; }
  23. 23
  24. 24 /// <summary>
  25. 25 /// 广告链接
  26. 26 /// </summary>
  27. 27 public string Url { get; set; }
  28. 28
  29. 29 /// <summary>
  30. 30 /// 备注
  31. 31 /// </summary>
  32. 32 public string Remark { get; set; }
  33. 33 }
  34. 34 }

展示类AdvertisementViewModels:

  1. 1 namespace Wchl.WMBlog.Model.VeiwModels
  2. 2 {
  3. 3 /// <summary>
  4. 4 /// 广告类
  5. 5 /// </summary>
  6. 6 public class AdvertisementViewModels
  7. 7 {
  8. 8 /// <summary>
  9. 9 /// 分类ID
  10. 10 /// </summary>
  11. 11 public int Id { get; set; }
  12. 12 /// <summary>
  13. 13 /// 创建时间
  14. 14 /// </summary>
  15. 15 public DateTime Createdate { get; set; }
  16. 16
  17. 17 /// <summary>
  18. 18 /// 广告图片
  19. 19 /// </summary>
  20. 20 public string ImgUrl { get; set; }
  21. 21
  22. 22 /// <summary>
  23. 23 /// 广告标题
  24. 24 /// </summary>
  25. 25 public string Title { get; set; }
  26. 26
  27. 27 /// <summary>
  28. 28 /// 广告链接
  29. 29 /// </summary>
  30. 30 public string Url { get; set; }
  31. 31
  32. 32 /// <summary>
  33. 33 /// 备注
  34. 34 /// </summary>
  35. 35 public string Remark { get; set; }
  36. 36 }
  37. 37 }

表约束AdvertisementMap:

  1. 1 namespace Wchl.WMBlog.Model.Maps
  2. 2 {
  3. 3 public class AdvertisementMap: EntityTypeConfiguration<Advertisement>
  4. 4 {
  5. 5 public AdvertisementMap()
  6. 6 {
  7. 7 this.HasKey(p => p.Id);
  8. 8 this.Property(p => p.ImgUrl).HasMaxLength(512);
  9. 9 this.Property(p => p.Title).HasMaxLength(64);
  10. 10 this.Property(p => p.Url).HasMaxLength(256);
  11. 11 }
  12. 12 }
  13. 13 }

这里实现的是添加图片自动上传:

五、博客系统右侧统计

5.1效果显示,这里的统计主要是对发布时间、阅读排行、评论排行做了统计。

后台实现代码:

部分布局视图代码:

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

这里重点讲讲怎么在EF中执行SQL语句:

在仓储父类的实现中这里传入的实体就是需要展示表内容的类:

六、博客系统小结

现阶段博客系统已经完成了前台展示,后台发布基本功能,接下来打算在后台添加一个权限模块,个人能力有限,代码水平不够好,也许我这样的代码还入不了大神的法眼,等我把权限做完之后,我会一点一点的来修改代码。

其实我写代码的时间不长,主要是每次想功能怎么实现的时候,要把每一步都想到,感觉编程,真正实现功能的开发编码的时间只有40%左右。

如果大家对这个有什么意见和想法,可以提出来,我会尽量,去修改的,谢谢了。

补充内容:

根据园友提出的补漏部分说明:

这个QueryByBeginPage是在仓储层写的一个查询分页的功能,是为了配合DataTables使用的。

  1. 1 /// <summary>
  2. 2 /// 从第几条开始用于DataTables
  3. 3 /// </summary>
  4. 4 /// <typeparam name="TKey"></typeparam>
  5. 5 /// <param name="pageIndex">第几页开始</param>
  6. 6 /// <param name="pagesize">一页几条</param>
  7. 7 /// <param name="rowcount">一共多少条</param>
  8. 8 /// <param name="predicate">条件</param>
  9. 9 /// <param name="keySelector">排序关键字</param>
  10. 10 /// <param name="IsQueryOrderBy">升序还是降序</param>
  11. 11 /// <returns></returns>
  12. 12 public List<TEntity> QueryByBeginPage<TKey>(int pageIndex, int pagesize, out int rowcount, Expression<Func<TEntity, bool>> predicate, Expression<Func<TEntity, TKey>> keySelector, bool IsQueryOrderBy)
  13. 13 {
  14. 14 rowcount = _dbSet.Count(predicate);
  15. 15 if (IsQueryOrderBy)
  16. 16 {
  17. 17 return _dbSet.Where(predicate).OrderBy(keySelector).Skip(pageIndex).Take(pagesize).ToList();
  18. 18 }
  19. 19 else
  20. 20 {
  21. 21 return _dbSet.Where(predicate).OrderByDescending(keySelector).Skip(pageIndex).Take(pagesize).ToList();
  22. 22 }
  23. 23 }

这个TopgbViewModels是查询统计留言排行用的一个类,是根据你数据库查询出来表建的相应的类

  1. 1 /// <summary>
  2. 2 /// 留言排名展示类
  3. 3 /// </summary>
  4. 4 public class TopgbViewModels
  5. 5 {
  6. 6 /// <summary>博客ID
  7. 7 ///
  8. 8 /// </summary>
  9. 9 public int? blogId { get; set; }
  10. 10
  11. 11 /// <summary>
  12. 12 /// 评论数量
  13. 13 /// </summary>
  14. 14 public int counts { get; set; }
  15. 15
  16. 16 /// <summary>博客标题
  17. 17 ///
  18. 18 /// </summary>
  19. 19 public string btitle { get; set; }
  20. 20 }

有什么不明白的地方都可以跟我留言,我会尽量写清楚点,让大家看的明白点。

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

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

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

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

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

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

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

  4. 从零开始,搭建博客系统MVC5+EF6搭建框架(3),添加Nlog日志、缓存机制(MemoryCache、RedisCache)、创建控制器父类BaseController

    一.回顾系统进度以及本章概要 目前博客系统已经数据库创建.以及依赖注入Autofac集成,接下来就是日志和缓存集成,这里日志用的是Nlog,其实还有其他的日志框架如log4,这些博客园都有很多介绍,这 ...

  5. 从零开始,搭建博客系统MVC5+EF6搭建框架(2),测试添加数据、集成Autofac依赖注入

    一.测试仓储层.业务层是否能实现对数据库表的操作 1.创建IsysUserInfoRepository接口来继承IBaseRepository父接口 namespace Wchl.WMBlog.IRe ...

  6. 一百二十六:CMS系统之轮播图管理页面布局和添加轮播图的模态对话框制作

    视图 @bp.route('/banners/')@login_required@permission_required(CMSPersmission.POSTER)def banners(): re ...

  7. 【干货】利用MVC5+EF6搭建博客系统(四)(下)前后台布局实现、发布博客以及展示

    二.博客系统后台布局实现 2.1.这里所用的是MVC的布局页来实现的,后台主要分为三部分:导航.菜单.主要内容 代码实现: 这里把后台单独放在一个区域里面,所以我这里建立一个admin的区域 在布局页 ...

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

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

  9. day76:luffy:项目前端环境搭建&轮播图的实现

    目录 1.项目前端环境搭建 1.创建项目目录 2.前端初始化全局变量和全局方法 3.跨域CORS 4.axios配置 2.轮播图功能的实现 1.安装依赖模块 2.上传文件相关配置 3.注册home子应 ...

随机推荐

  1. 学习笔记:Hashtable和HashMap

    学了这么些天的基础知识发现自己还是个门外汗,难怪自己一直混的不怎么样.但这样的恶补不知道有没有用,是不是过段时间这些知识又忘了呢?这些知识平时的工作好像都是随拿随用的,也并不是平时一点没有关注过这些基 ...

  2. .NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长

    一个 asp.net core 站点,之前运行在Linux 服务器上,运行一段时间后有时站点会挂掉,在日志中记录很多“EMFILE too many open files”的错误: Microsoft ...

  3. 【读书笔记】Asp.Net MVC 上传图片到数据库(会的绕行)

    之前上传图片的做法都是上传到服务器上的文件夹中,再将url保存到数据库.其实在MVC中将图片上传到数据库很便捷的事情,而且不用去存url了.而且这种方式支持ie6(ie6不支持jquery自动提交fo ...

  4. C语言 · 未名湖边的烦恼

    问题描述 每年冬天,北大未名湖上都是滑冰的好地方.北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩. 每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个.现在 ...

  5. .NET 基础 一步步 一幕幕 [注释、命名规则、访问修饰符、数据类型、常量、变量]

    注释.命名规则.访问修饰符.数据类型.常量.变量 话说一个不会写注释的程序猿的不是一个好吃货,我们本篇就从注释开始说起好了. 在C#中有三种注释: 第一种:单行注释  以//开头,后面的就是注释内容 ...

  6. 解决 PLSQL Developer无法连接数据库

    问题:PLSQL Developer无法连接数据库 原因:PLSQL Developer不支持x64的Oracle客户端 解决方案:1.下载instantclient-basic-nt-12.1.0. ...

  7. js创建对象的高级模式

    hello,安瑞万.第一次写博客,心情很激动啊.要是说的不好,你来打我啊?反正你也不知道我家地址.好了,不扯了.进入正题:要是写的不好欢迎大家来批评指导. what:创建对象的三种模式 --1,门户大 ...

  8. JS数字计算精度误差的解决方法

    本篇文章主要是对javascript避免数字计算精度误差的方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助. 如果我问你 0.1 + 0.2 等于几?你可能会送我一个白眼,0.1 + 0. ...

  9. Utility3:Understand Dashboard Report

    To see data in the SQL Server Utility dashboard, select the top node in the Utility Explorer tree - ...

  10. Effective Modern C++ 42 Specific Ways to Improve Your Use of C++11 and C++14

    Item 1: Understand template type deduction. Item 2: Understand auto type deduction. Item 3: Understa ...