【干货】利用MVC5+EF6搭建博客系统(四)(下)前后台布局实现、发布博客以及展示
二、博客系统后台布局实现
2.1.这里所用的是MVC的布局页来实现的,后台主要分为三部分:导航、菜单、主要内容
代码实现:
这里把后台单独放在一个区域里面,所以我这里建立一个admin的区域
在布局页_Layout.cshtml引入公共的一些css文件以及js文件(ZUI:http://zui.sexy/。metisMenu:http://mm.onokumus.com/)
布局页代码_Layout.cshtml:
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>@ViewBag.Title - 博客系统后台管理</title> <link href="~/Content/lib/zui/css/zui.css" rel="stylesheet" /> <link href="~/Content/lib/zui/css/zui-theme.css" rel="stylesheet" /> <link href="~/Content/lib/font-awesome/css/font-awesome.css" rel="stylesheet" /> <link href="~/Content/lib/metisMenu/metisMenu.css" rel="stylesheet" /> <link href="~/Content/CSS/index.css" rel="stylesheet" /> @RenderSection("stylesheet", required: false) <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script> <script src="~/Content/lib/zui/js/zui.js"></script> <script src="~/Content/lib/metisMenu/metisMenu.js"></script> <script src="~/Content/JS/index.js"></script> </head> <body> <!--header--> <header> <div class="navbar navbar-inverse " role="navigation"> <div class="navbar-header"> <!--移动设备上的导航切换按钮--> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse-example"> <span class="sr-only">切换导航</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <!--品牌名称或logo--> <a class="navbar-brand">系统后台</a> </div> <div class="collapse navbar-collapse navbar-collapse-example"> <ul class="nav navbar-nav navbar-right"> <li><a><i class="icon icon-user"></i> 您好,admin</a></li> <li><a><i class="icon icon-exchange"></i> 隐藏菜单</a></li> <li><a href="/admin/Home"><i class="icon icon-home"></i> 首页</a></li> <li><a><i class="icon icon-question-sign"></i> 帮助</a></li> <li><a><i class="icon icon-off"></i> 退出</a></li> </ul> </div> </div> </header> <!--header end--> <!--content--> <div class="clearfix"> @Html.Partial("_sidebar") <div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 rightmain"> <div class="col-sm-12 col-md-12 rightcontent"> @RenderBody() </div> </div> </div> <!--content end--> <!--footer--> <footer class="col-md-12 footer footerstyle"> <p>© @DateTime.Now.Year - 我的博客系统</p> </footer> <!--footer end--> <script src="https://cdn.bootcss.com/jquery-validate/1.17.0/jquery.validate.js"></script> <script src="https://cdn.bootcss.com/jquery-validation-unobtrusive/3.2.6/jquery.validate.unobtrusive.js"></script> <script src="https://cdn.bootcss.com/jquery-ajax-unobtrusive/3.2.4/jquery.unobtrusive-ajax.js"></script> @RenderSection("scripts", required: false) </body> </html>
菜单部分页_sidebar.cshtml代码:
@{ string url = Request.Url.ToString().ToLower(); } @if (url.Contains("home")) { <aside class="col-sm-3 col-md-2 sidebar"> <nav class="sidebar-nav"> <ul class="metismenu" id="menu"> <li class="active"> <a href="#" aria-expanded="true"> <i class="icon icon-github"></i> 系统统计<i class="fa arrow fa-fw"></i> </a> <ul aria-expanded="true"> <li> <a href="/admin/statistics/visitor"> <i class="icon icon-list"></i> 访问统计 </a> </li> <li> <a href="/admin/statistics/usesr"> <i class="icon icon-github"></i> 用户统计 </a> </li> </ul> </li> <li> <a href="#" aria-expanded="false">博客管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="/admin/BlogArticle/Index">博客列表</a></li> <li><a href="/admin/BlogArticle/Add">发布博客</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">广告管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="@Url.Action("index", "Advertisement")">轮播图管理</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">用户管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">修改信息</a></li> <li><a href="#">修改密码</a></li> <li> <a href="#" aria-expanded="false">用户信息管理<span class="fa plus-times"></span></a> <ul aria-expanded="false"> <li><a href="#">修改信息</a></li> <li><a href="#">修改密码</a></li> </ul> </li> </ul> </li> <li> <a href="#" aria-expanded="false">权限管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">用户授权</a></li> <li><a href="#">用户组管理</a></li> <li><a href="#">用户组授权</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">日志管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">用户日志</a></li> <li><a href="#">系统日志</a></li> </ul> </li> </ul> </nav> </aside> } else if (url.Contains("blogarticle")) { <aside class="col-sm-3 col-md-2 sidebar"> <nav class="sidebar-nav"> <ul class="metismenu" id="menu"> <li> <a href="#" aria-expanded="true"> <i class="icon icon-github"></i> 系统统计<i class="fa arrow fa-fw"></i> </a> <ul aria-expanded="true"> <li> <a href="/admin/statistics/visitor"> <i class="icon icon-list"></i> 访问统计 </a> </li> <li> <a href="/admin/statistics/usesr"> <i class="icon icon-github"></i> 用户统计 </a> </li> </ul> </li> <li class="active"> <a href="#" aria-expanded="false">博客管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="/admin/BlogArticle/Index">博客列表</a></li> <li><a href="/admin/BlogArticle/Add">发布博客</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">广告管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="@Url.Action("index", "Advertisement")">轮播图管理</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">用户管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">修改信息</a></li> <li><a href="#">修改密码</a></li> <li> <a href="#" aria-expanded="false">用户信息管理<span class="fa plus-times"></span></a> <ul aria-expanded="false"> <li><a href="#">修改信息</a></li> <li><a href="#">修改密码</a></li> </ul> </li> </ul> </li> <li> <a href="#" aria-expanded="false">权限管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">用户授权</a></li> <li><a href="#">用户组管理</a></li> <li><a href="#">用户组授权</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">日志管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">用户日志</a></li> <li><a href="#">系统日志</a></li> </ul> </li> </ul> </nav> </aside> } else if (url.Contains("advertisement")) { <aside class="col-sm-3 col-md-2 sidebar"> <nav class="sidebar-nav"> <ul class="metismenu" id="menu"> <li> <a href="#" aria-expanded="true"> <i class="icon icon-github"></i> 系统统计<i class="fa arrow fa-fw"></i> </a> <ul aria-expanded="true"> <li> <a href="/admin/statistics/visitor"> <i class="icon icon-list"></i> 访问统计 </a> </li> <li> <a href="/admin/statistics/usesr"> <i class="icon icon-github"></i> 用户统计 </a> </li> </ul> </li> <li> <a href="#" aria-expanded="false">博客管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="/admin/BlogArticle/Index">博客列表</a></li> <li><a href="/admin/BlogArticle/Add">发布博客</a></li> </ul> </li> <li class="active"> <a href="#" aria-expanded="false">广告管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="@Url.Action("index", "Advertisement")">轮播图管理</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">用户管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">修改信息</a></li> <li><a href="#">修改密码</a></li> <li> <a href="#" aria-expanded="false">用户信息管理<span class="fa plus-times"></span></a> <ul aria-expanded="false"> <li><a href="#">修改信息</a></li> <li><a href="#">修改密码</a></li> </ul> </li> </ul> </li> <li> <a href="#" aria-expanded="false">权限管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">用户授权</a></li> <li><a href="#">用户组管理</a></li> <li><a href="#">用户组授权</a></li> </ul> </li> <li> <a href="#" aria-expanded="false">日志管理<i class="fa arrow fa-fw"></i></a> <ul aria-expanded="false"> <li><a href="#">用户日志</a></li> <li><a href="#">系统日志</a></li> </ul> </li> </ul> </nav> </aside> }
其实我这个菜单选中的效果做的很垃圾,我自己都觉得不要,但是目前我也只能想到这个方法,因为每次加载一个嵌套的页面就会从新去加载一次布局页_Layout.cshtml的内容,我这个菜单是有一个active选中的样式的,这个是菜单插件里面已经写好了,这里遇到的问题就是每次刷新都会把页面选中效果设置到默认的菜单上,假如点击了发布博客菜单应该显示博客管理这个菜单内容,但是从新加载的时候就会回到默认的系统统计菜单上,所以这里就用地址路径来判断应该显示那个菜单,方法真的很笨,见谅,各位。
2.2博客信息添加功能实现
在52MVCBlog.Model程序集的Models文件创建一个BlogArticle类,然后在创建一个文件VeiwModels,Models文件夹里面的类是用来生成数据库对应的表,而VeiwModels文件夹里面对应的类是用来在view视图页面展示数据用的,当你一个表字段很多不需要所有数据都展示,或者要做一些处理计算的类,这样就需要一个VeiwModels类来分离。
BlogArticle类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Model.Models { /// <summary> /// 博客文章 /// </summary public class BlogArticle { /// <summary> /// /// </summary> public int bID { get; set; } /// <summary> /// 创建人 /// </summary> public string bsubmitter { get; set; } /// <summary> /// 博客标题 /// </summary> public string btitle { get; set; } /// <summary> /// 类别 /// </summary> public string bcategory { get; set; } /// <summary> /// 内容 /// </summary> public string bcontent { get; set; } /// <summary> /// 访问量 /// </summary> public int btraffic { get; set; } /// <summary> /// 评论数量 /// </summary> public int bcommentNum { get; set; } /// <summary> /// 修改时间 /// </summary> public DateTime bUpdateTime { get; set; } /// <summary> /// 创建时间 /// </summary> public System.DateTime bCreateTime { get; set; } /// <summary> /// 备注 /// </summary> public string bRemark { get; set; } } }
BlogViewModels类:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Model.Models { /// <summary> /// 博客信息展示类 /// </summary> public class BlogViewModels { /// <summary> /// /// </summary> public int bID { get; set; } /// <summary> /// 创建人 /// </summary> public string bsubmitter { get; set; } /// <summary> /// 博客标题 /// </summary> public string btitle { get; set; } /// <summary> /// 摘要 /// </summary> public string digest { get; set; } /// <summary> /// 上一篇 /// </summary> public string previous { get; set; } /// <summary> /// 上一篇id /// </summary> public int previousID { get; set; } /// <summary> /// 下一篇 /// </summary> public string next { get; set; } /// <summary> /// 下一篇id /// </summary> public int nextID { get; set; } /// <summary> /// 类别 /// </summary> public string bcategory { get; set; } /// <summary> /// 内容 /// </summary> public string bcontent { get; set; } /// <summary> /// 访问量 /// </summary> public int btraffic { get; set; } /// <summary> /// 评论数量 /// </summary> public int bcommentNum { get; set; } /// <summary> /// 修改时间 /// </summary> public DateTime bUpdateTime { get; set; } /// <summary> /// 创建时间 /// </summary> public System.DateTime bCreateTime { get; set; } /// <summary> /// 备注 /// </summary> public string bRemark { get; set; } } }
在maps文件夹中添加相应的约束
BlogArticleMap类:
using _52MVCBlog.Model.Models; using System; using System.Collections.Generic; using System.Data.Entity.ModelConfiguration; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Model.Maps { public class BlogArticleMap: EntityTypeConfiguration<BlogArticle> { public BlogArticleMap() { this.HasKey(p => p.bID); this.Property(p => p.btitle).HasMaxLength(256); this.Property(p => p.bsubmitter).HasMaxLength(60); this.Property(p => p.bcontent).HasColumnType("Text").IsMaxLength(); } } }
然后在控制台使用更新数据库命令:add-migration 52MVCBlogDB与update database -force,一定要选择model层(如果出现update : 无法将“update”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。执行Install-Package EntityFramework后重试即可)
创建好了表,然后就是在仓储层以及业务层创建相应的接口和实现类
IBlogArticleRepository接口类代码:
using _52MVCBlog.IRepository.Base; using _52MVCBlog.Model.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.IRepository { public interface IBlogArticleRepository : IBaseRepository<BlogArticle> { } }
BlogArticleRepository类代码:
using _52MVCBlog.IRepository; using _52MVCBlog.Model.Models; using _52MVCBlog.Repository.Base; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Repository { public class BlogArticleRepository : BaseRepository<BlogArticle>, IBlogArticleRepository { } }
在52MVCBlog.Common程序集下新建ToolsHelper文件夹,新建Tools.cs公共工具类
Tools公共工具类代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Web; using System.IO; namespace _52MVCBlog.Common.ToolsHelper { /// <summary> /// 公共实用工具 /// </summary> public class Tools { #region 计算两个时间差值的函数,返回时间差的绝对值 /// <summary> /// 计算两个时间差值的函数,返回时间差的绝对值: /// </summary> /// <param name="DateTime1"></param> /// <param name="DateTime2"></param> /// <returns></returns> public string DateDiff(DateTime DateTime1, DateTime DateTime2) { string dateDiff = null; try { TimeSpan ts1 = new TimeSpan(DateTime1.Ticks); TimeSpan ts2 = new TimeSpan(DateTime2.Ticks); TimeSpan ts = ts1.Subtract(ts2).Duration(); dateDiff = ts.Days.ToString() + "天" + ts.Hours.ToString() + "小时" + ts.Minutes.ToString() + "分钟" + ts.Seconds.ToString() + "秒"; } catch { } return dateDiff; } #endregion #region 去除富文本中的HTML标签 /// <summary> /// 去除富文本中的HTML标签 /// </summary> /// <param name="html"></param> /// <param name="length"></param> /// <returns></returns> public static string ReplaceHtmlTag(string html, int length = 0) { string strText = System.Text.RegularExpressions.Regex.Replace(html, "<[^>]+>", ""); strText = System.Text.RegularExpressions.Regex.Replace(strText, "&[^;]+;", ""); if (length>0&&strText.Length>length) { return strText.Substring(0, length); } return strText; } #endregion #region 上传文件方法,默认生成日期文件夹,MVC使用 /// <summary> /// 上传文件方法,默认生成日期文件夹,MVC使用 /// 返回文件名 /// </summary> /// <param name="PostedFile">mvc后台获取的</param> /// <param name="allowExtensions">允许上传的扩展文件名类型,如:string[] allowExtensions = { ".doc", ".xls", ".ppt", ".jpg", ".gif" };</param> /// <param name="maxLength">允许上传的最大大小,以M为单位</param> /// <param name="savePath">保存文件的目录,注意是绝对路径,如:Server.MapPath("~/upload/");</param> /// <param name="gendatedir">是否生成日期文件夹</param> /// <param name="guidname">是否是GUID名字,默认true</param> /// <param name="savename">保存文件名(不带后缀),如果非空则以此文件名保存</param> public static string Upload_MVC(HttpPostedFileBase PostedFile, string[] allowExtensions, int maxLength, string savePath, bool gendatedir = true, bool guidname = true, string savename = "") { //文件格式是否允许上传 bool fileAllow = false; //检查文件大小,ContentLength获取的是字节,转成M的时候要除以2次1024 if (PostedFile.ContentLength/1024/1024>=maxLength) { throw new Exception("只能上传小于" + maxLength + "M的文件!"); } //取得长传文件的扩展名,并转换成小写字母 string fileExtension = System.IO.Path.GetExtension(PostedFile.FileName).ToLower(); string tmp = "";//存储允许上传的文件的后缀名 //检查扩展文件名是否符合限定类型 for (int i = 0; i < allowExtensions.Length; i++) { tmp+=i==allowExtensions.Length-1?allowExtensions[i]:allowExtensions[i] + ","; if (fileExtension==allowExtensions[i]) { fileAllow = true; } } if (fileAllow) { try { string dateDir = DateTime.Now.ToString("yyyyMMdd"); if (!Directory.Exists(savePath+dateDir)&&gendatedir) { Directory.CreateDirectory(savePath + dateDir); } string saveName = guidname ? Guid.NewGuid() + fileExtension : PostedFile.FileName; if (!string.IsNullOrEmpty(savename)) { saveName = savename + fileExtension; } string path = gendatedir ? savePath + dateDir + "/" + saveName : savePath + saveName; //存储文件到文件夹 PostedFile.SaveAs(path); return gendatedir ? dateDir + "/" + saveName : saveName; } catch (Exception ex) { throw new Exception(ex.Message); } } else { throw new Exception("文件格式(" + fileExtension + ")不符,可以上传的文件格式为:" + tmp); } } #endregion } }
IBlogArticleServices接口类代码:
using _52MVCBlog.IService.Base; using _52MVCBlog.Model.Models; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.IService { public interface IBlogArticleServices : IBaseServices<BlogArticle> { /// <summary> /// 获取视图博客详情信息 /// </summary> /// <param name="id"></param> /// <returns></returns> BlogViewModels getBlogDetails(int id); } }
BlogArticleServices类代码:
using _52MVCBlog.Common.ToolsHelper; using _52MVCBlog.IRepository; using _52MVCBlog.IService; using _52MVCBlog.Model.Models; using _52MVCBlog.Service.Base; using AutoMapper; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Service { public class BlogArticleServices : BaseServices<BlogArticle>, IBlogArticleServices { #region Autofac依赖注入 private IBlogArticleRepository dal; public BlogArticleServices(IBlogArticleRepository dal) { this.dal = dal; base.baseDal = dal; } #endregion /// <summary> /// 获取视图博客详情信息 /// </summary> /// <param name="id"></param> /// <returns></returns> public BlogViewModels getBlogDetails(int id) { BlogArticle blogArticle = dal.QueryWhere(a => a.bID == id).FirstOrDefault(); BlogArticle nextblog = dal.QueryWhere(a => a.bID == id - 1).FirstOrDefault(); BlogArticle prevblog = dal.QueryWhere(a => a.bID == id + 1).FirstOrDefault(); blogArticle.btraffic += 1; dal.Edit(blogArticle, new string[] { "btraffic" }); dal.SaverChanges(); //AutoMapper自动映射 //注册映射 Mapper.Initialize(cfg => cfg.CreateMap<BlogArticle, BlogViewModels>()); //进行映射 BlogViewModels models = Mapper.Map<BlogArticle, BlogViewModels>(blogArticle); if (nextblog != null) { models.next = nextblog.btitle; models.nextID = nextblog.bID; } if (prevblog != null) { models.previous = prevblog.btitle; models.previousID = prevblog.bID; } models.digest = Tools.ReplaceHtmlTag(blogArticle.bcontent).Length > 100 ? Tools.ReplaceHtmlTag(blogArticle.bcontent).Substring(0, 200) : Tools.ReplaceHtmlTag(blogArticle.bcontent); return models; } } }
2.3博客添加页面实现功能
在区域admin的控制器下创建一个Add方法用来展示页面。
Add方法:
public ActionResult Add() { return View(); }
然后View添加视图选择使用布局页
Add局页代码:
@{ ViewBag.Title = "添加博客"; } <link href="~/Content/animate.css" rel="stylesheet" /> <link href="~/Content/CSS/blogArticleStyle.css" rel="stylesheet" /> <script src="https://unpkg.com/wangeditor/release/wangEditor.min.js"></script> <script src="https://cdn.bootcss.com/jquery-ajax-unobtrusive/3.2.4/jquery.unobtrusive-ajax.js"></script> <script type="text/javascript"> $(function () { // 获取元素 var E = window.wangEditor; // 生成编辑器 var editor = new E("#bcontent"); // 自定义菜单 editor.customConfig.menus = [ 'head', // 标题 'bold', // 粗体 'italic', // 斜体 'underline', // 下划线 'strikeThrough', // 删除线 'foreColor', // 文字颜色 'backColor', // 背景颜色 'link', // 插入链接 'list', // 列表 'justify', // 对齐方式 'quote', // 引用 'emoticon', // 表情 'image', // 插入图片 'table', // 表格 'video', // 插入视频 'code', // 插入代码 'undo', // 撤销 'redo' // 重复 ]; //上传图片(举例) editor.customConfig.uploadImgServer = '/admin/BlogArticle/upload'; //editor.customConfig.debug = true; // 将 timeout 时间改为 3s editor.customConfig.uploadImgTimeout = 1000000; editor.customConfig.uploadImgHooks = { //before: function (xhr, editor, files) { // // 图片上传之前触发 // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件 // // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传 // // return { // // prevent: true, // // msg: '放弃上传' // // } // alert("before"); //}, //success: function (xhr, editor, result) { // // 图片上传并返回结果,图片插入成功之后触发 // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果 // alert("success"); //}, //fail: function (xhr, editor, result) { // alert("fail"); // // 图片上传并返回结果,但图片插入错误时触发 // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果 //}, //error: function (xhr, editor) { // // 图片上传出错时触发 // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象 // alert("error"); //}, //timeout: function (xhr, editor) { // // 图片上传超时时触发 // // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象 // alert("timeout"); //}, // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错) customInsert: function (insertImg, result, editor) { // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!) // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果 // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片: var url = JSON.parse(result).data[0] insertImg(url) // result 必须是一个 JSON 格式字符串!!!否则报错 alert("customInsert"); } } editor.create(); }); //添加博文之后 function afterAddBlog(data) { var serverData = data.split(':'); if (serverData[0] == "ok") { alert(serverData[1]); window.location.reload(); } }; </script> <div class="blogcontent"> <!-- head star --> <div class="tnav row border-bottom white-bg page-heading"> <div class="col-sm-4"> <h2 class="fl">博客后台</h2> <ol class="breadcrumb fl"> <li><a href="/admin/Home">博客管理</a></li> <li><strong>发布博客</strong></li> </ol> </div> </div> <!-- head end --> <!-- form star --> <div class=""> <div class="wrapper wrapper-content animated fadeInUp" style="height:600px;padding-bottom:30px;overflow:auto"> @using (Ajax.BeginForm("Add", "BlogArticle", new { }, new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterAddBlog" }, new { @class = "form-horizontal" })) { <div class="form-group"> <label class="col-md-1 control-label">标题 :</label> <div class="col-md-11"> <input type='text' name='btitle' id='title' value='' class='form-control' placeholder='' /> </div> </div> <div class="form-group"> <label class="col-md-1 control-label">类别 :</label> <div class='col-md-2'> <select name='bcategory' id='original' class='form-control'> <option value='技术博文' selected='selected'>技术博文</option> <option value='随笔日志'>随笔日志</option> </select> </div> </div> <div class="form-group"> <label class="col-md-1 control-label">内容 :</label> <div class='col-md-11'> <div id="bcontent" class="text"> <p>请输入内容...</p> </div> </div> </div> <div class="form-group"> <div class="col-md-offset-1 col-md-10"> <input type='submit' id='submit' class='btn btn-info' value='保存' data-loading='稍候...' /> </div> </div> } </div> </div> <!-- form end --> </div>
效果图
在控制器中添加一个上传图片的方法upload,用于富文本编辑器上传图片
注意:wangEditor3使用手册有部分bug,后台必须返回给前台json格式,并且要通过监听函数进行解析显示图片
upload代码:
public ActionResult upload() { //文件保存目录路径 String savePath = "/upload/"; //定义允许上传的文件扩展名 Hashtable extTable = new Hashtable(); extTable.Add("image", "gif,jpg,jpeg,png,bmp"); extTable.Add("flash", "swf,flv"); extTable.Add("media", "swf,flv,mp3,wav,wma,wmv,mid,avi,mpg,asf,rm,rmvb"); extTable.Add("file", "doc,docx,xls,xlsx,ppt,htm,html,txt,zip,rar,gz,bz2"); //最大文件大小 int maxSize = 1000000; HttpPostedFileBase imgFile = Request.Files[0]; if (imgFile == null) return Content("error|请选择文件。"); String dirPath = Server.MapPath(savePath); if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); String dirName = Request.QueryString["dir"]; if (String.IsNullOrEmpty(dirName)) dirName = "image"; if (!extTable.ContainsKey(dirName)) return Content("error|目录名不正确。"); String fileName = imgFile.FileName; String fileExt = Path.GetExtension(fileName).ToLower(); if (imgFile.InputStream == null || imgFile.InputStream.Length > maxSize) return Content("error|上传文件大小超过限制。"); if (String.IsNullOrEmpty(fileExt) || Array.IndexOf(((String)extTable[dirName]).Split(','), fileExt.Substring(1).ToLower()) == -1) return Content("error|上传文件扩展名是不允许的扩展名。\n只允许" + ((String)extTable[dirName]) + "格式。"); //创建文件夹 dirPath += dirName + "/"; if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); String ymd = DateTime.Now.ToString("yyyyMMdd", DateTimeFormatInfo.InvariantInfo); dirPath += ymd + "/"; if (!Directory.Exists(dirPath)) Directory.CreateDirectory(dirPath); String newFileName = DateTime.Now.ToString("yyyyMMddHHmmss_ffff", DateTimeFormatInfo.InvariantInfo) + fileExt; String filePath = dirPath + newFileName; imgFile.SaveAs(filePath); String fileUrl = "http://" + Request.Url.Authority + savePath + "image/" + ymd + "/" + newFileName; JObject jObj=new JObject(); jObj.Add("errno", 0); jObj.Add("data", new JArray(fileUrl)); return Json(JsonConvert.SerializeObject(jObj)); }
提交博客使用的是异步提交
add方法:
@{ ViewBag.Title = "添加博客"; } <link href="~/Content/animate.css" rel="stylesheet" /> <link href="~/Content/CSS/blogArticleStyle.css" rel="stylesheet" /> <script src="https://unpkg.com/wangeditor/release/wangEditor.min.js"></script> @*<script src="https://cdn.bootcss.com/jquery-ajax-unobtrusive/3.2.4/jquery.unobtrusive-ajax.js"></script>*@ <script type="text/javascript"> $(function () { // 获取元素 var E = window.wangEditor; // 生成编辑器 var editor = new E("#bcontentdiv"); // 自定义菜单 editor.customConfig.menus = [ 'head', // 标题 'bold', // 粗体 'italic', // 斜体 'underline', // 下划线 'strikeThrough', // 删除线 'foreColor', // 文字颜色 'backColor', // 背景颜色 'link', // 插入链接 'list', // 列表 'justify', // 对齐方式 'quote', // 引用 'emoticon', // 表情 'image', // 插入图片 'table', // 表格 'video', // 插入视频 'code', // 插入代码 'undo', // 撤销 'redo' // 重复 ]; //上传图片(举例) editor.customConfig.uploadImgServer = '/admin/BlogArticle/upload'; //editor.customConfig.debug = true; // 将 timeout 时间改为 3s editor.customConfig.uploadImgTimeout = 1000000; editor.customConfig.uploadImgHooks = { // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错) customInsert: function (insertImg, result, editor) { // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!) // insertImg 是插入图片的函数,editor 是编辑器对象,result 是服务器端返回的结果 // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片: var url = JSON.parse(result).data[0] insertImg(url) // result 必须是一个 JSON 格式字符串!!!否则报错 alert("customInsert"); } } //wangEditor 从v3版本开始不支持 textarea ,但是可以通过onchange来实现 textarea 中提交富文本内容。 var $text1 = $('#bcontent') editor.customConfig.onchange = function (html) { // 监控变化,同步更新到 textarea $text1.val(html) } editor.create(); }); //添加博文之后 function afterAddBlog(data) { var serverData = data.split(':'); if (serverData[0] == "ok") { alert(serverData[1]); window.location.reload(); } }; </script> <div class="blogcontent"> <!-- head star --> <div class="tnav row border-bottom white-bg page-heading"> <div class="col-sm-4"> <h2 class="fl">博客后台</h2> <ol class="breadcrumb fl"> <li><a href="/admin/Home">博客管理</a></li> <li><strong>发布博客</strong></li> </ol> </div> </div> <!-- head end --> <!-- form star --> <div class=""> <div class="wrapper wrapper-content animated fadeInUp" style="height:600px;padding-bottom:30px;overflow:auto"> @using (Ajax.BeginForm("Add", "BlogArticle", new { }, new AjaxOptions() { HttpMethod = "post", OnSuccess = "afterAddBlog" }, new { @class = "form-horizontal" })) { <div class="form-group"> <label class="col-md-1 control-label">标题 :</label> <div class="col-md-11"> <input type='text' name='btitle' id='title' value='' class='form-control' placeholder='' /> </div> </div> <div class="form-group"> <label class="col-md-1 control-label">类别 :</label> <div class='col-md-2'> <select name='bcategory' id='original' class='form-control'> <option value='技术博文' selected='selected'>技术博文</option> <option value='随笔日志'>随笔日志</option> </select> </div> </div> <div class="form-group"> <label class="col-md-1 control-label">内容 :</label> <div class='col-md-11'> <div id="bcontentdiv" class="text"> <p>请输入内容...</p> </div> <textarea id="bcontent" rows="18" name="bcontent" class='form-control hidden'> </textarea> </div> </div> <div class="form-group"> <div class="col-md-offset-1 col-md-10"> <input type='submit' id='submit' class='btn btn-info' value='保存' data-loading='稍候...' /> </div> </div> } </div> </div> <!-- form end --> </div>
记住在使用之前需要把接口和对应的方法实现在构造方法中调用
ps:可能会遇到执行两次Ajax.BeginForm的情况,原因是多引用了一次jquery.unobtrusive-ajax.js文件,删掉即可。
三、博客系统前台布局实现
3.1接下来就改前台展示部分,同样使用的是布局页
设计页面如下:
前台布局页_Layout.cshtml代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link href="~/Content/lib/zui/css/zui.css" rel="stylesheet" /> <link href="~/Content/CSS/zui-blog-theme.css" rel="stylesheet" /> <link href="~/Content/CSS/zui-theme-blue.css" rel="stylesheet" /> <link href="~/Content/CSS/HomeIndex.css" rel="stylesheet" /> <link href="~/Content/CSS/pagerstyles.css" rel="stylesheet" /> <title>@ViewBag.Title - 52MVC博客</title> </head> <body> <!--导航部分--> @Html.Partial("_NavbarPage") <!--导航部分--> <!--主体内容--> <div class="main"> <div class="row"> <!--左边主要内容--> @*<article style="margin-top: 10px;"> <div class="col-md-8" id="leftmain"> @RenderBody() </div> </article>*@ <!--左边主要内容--> <!--右边栏--> @{ if (ViewBag.controllername != "statistical") { <article style="margin-top: 10px;"> <div class="col-md-8" id="leftmain"> @RenderBody() </div> </article> @Html.Partial("_RightPage") } else { @RenderBody() } } <!--右边栏--> </div> </div> <!--主体内容--> <!--底部版权部分--> @Html.Partial("_FooterPage") <script src="~/Content/lib/jquery-3.2.1.min.js"></script> <script src="~/Content/lib/zui/js/zui.js"></script> <script src="~/Content/lib/jquery.validate.js"></script> <script src="~/Content/lib/jquery.validate.unobtrusive.js"></script> <script src="~/Content/lib/jquery.unobtrusive-ajax.js"></script> <script type="text/javascript"> $(function () { //用于控制导航样式 var name = '@ViewBag.controllername' $('#' + name).attr("class", "active") }) </script> @RenderSection("scripts", false) <!--底部版权部分--> </body> </html>
部分布局页导航部分_NavbarPage代码:
<!--导航--> <nav class="navbar navbar-default navbar-fixed-top"> <div class="container"> <!--小屏幕导航按钮和logo--> <div class="navbar-header"> <button class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="index.html" class="navbar-brand">52 Blog</a> </div> <!--小屏幕导航按钮和logo--> <!--导航--> <div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> <li id="home"><a href="/home/index" id="index"><i class="icon icon-home"></i> 首页</a></li> <li id="blog"><a href="/blog/index" id="content"><i class="icon icon-list-alt"></i> 博文</a></li> <li><a href="/movie/index"><i class="icon icon-film"></i> 随笔</a></li> <li><a href="/statistical/index"><i class="icon icon-bar-chart"></i> 访问</a></li> <li><a href="/about/index"><span class="icon icon-tags"></span> 关于</a></li> </ul> <form class="navbar-form navbar-right" role="search"> <div class="form-group"> <input type="text" class="form-control" placeholder="搜索"> </div> <button type="submit" class="btn btn-primary"><i class="icon icon-search"></i> 搜索</button> </form> </div> <!--导航--> </div> </nav> <!--导航-->
在52MVCBlog.Model程序集下的Models添加查询统计留言排行用的一个类TopgbViewModels.cs代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace _52MVCBlog.Model.Models { /// <summary> /// 留言排名展示类 /// </summary> public class TopgbViewModels { /// <summary> /// 博客ID /// </summary> public int? blogId { get; set; } /// <summary> /// 评论数量 /// </summary> public int counts { get; set; } /// <summary> /// 博客标题 /// </summary> public string btitle { get; set; } } }
部分布局页右侧统计部分_RightPage代码:
<!--右边栏部分--> @using _52MVCBlog.Model.Models; <aside> <div class="col-md-4"> <section class="youbianlan"> <div class="panel-group"> <div class="panel"> <div class="panel-heading"> <div class="panel-title panel-info"> <h4>最新发布</h4> </div> </div> <div class="panel-body"> <ul> @{ if (ViewBag.blogtimelist != null) { for (int i = 0; i < ViewBag.blogtimelist.Count; i++) { <li><a href="/blog/Detail/@ViewBag.blogtimelist[i].bID">@ViewBag.blogtimelist[i].btitle</a></li> } } } </ul> </div> </div> </div> </section> <section class="youbianlan"> <div class="panel-group"> <div class="panel"> <div class="panel-heading"> <div class="panel-title panel-info"> <h4>阅读排行榜</h4> </div> </div> <div class="panel-body"> <ul> @{ if (ViewBag.blogtrafficlist != null) { for (int i = 0; i < ViewBag.blogtrafficlist.Count; i++) { <li><a href="/blog/Detail/@ViewBag.blogtrafficlist[i].bID">@ViewBag.blogtrafficlist[i].btitle</a></li> } } } </ul> </div> </div> </div> </section> <section class="youbianlan"> <div class="panel-group"> <div class="panel"> <div class="panel-heading"> <div class="panel-title panel-info"> <h4>评论排行榜</h4> </div> </div> <div class="panel-body"> <ul> @{ List<TopgbViewModels> list = ViewBag.blogguestbooklist as List<TopgbViewModels>; if (list != null && list.Any()) { if (list.Count < 10) { for (int i = 0; i < list.Count; i++) { <li><a href="/blog/Detail/@list[i].blogId">@list[i].btitle</a></li> } } else { for (int i = 0; i < list.Count; i++) { <li><a href="/blog/Detail/@list[i].blogId">@list[i].btitle</a></li> } } } } </ul> </div> </div> </div> </section> </div> </aside> <!--右边栏部分-->
部分布局页底部版权部分_FooterPage代码:
<!--页脚部分--> <div id="footer_wrapper" class="col-md-12"> <footer> <ul> <li><a href="content.html">版权信息</a></li> <li><a href="content.html">站点地图</a></li> <li><a href="content.html">联系我们</a></li> </ul> <p>Copyright ©2016 52Blog</p> </footer> </div> <!--页脚部分-->
在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下实现查询博客信息代码
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 a inner join BlogArticle as b on b.bID=a.blogId order by counts desc"; ViewBag.blogguestbooklist = GuestbookServices.RunProc<TopgbViewModels>(sql); return View(blogArticleList); } } }
然后创建一个Index视图页面
Index视图页代码
@model PagedList<_52MVCBlog.Model.Models.BlogArticle> @using Webdiyer.WebControls.Mvc @{ ViewBag.Title = "首页"; } <section id="lunbotu"> <div id="myNiceCarousel" class="carousel slide" data-ride="carousel"> <!-- 圆点指示器 --> <ol class="carousel-indicators"> <li data-target="#myNiceCarousel" data-slide-to="0" class="active"></li> <li data-target="#myNiceCarousel" data-slide-to="1"></li> <li data-target="#myNiceCarousel" data-slide-to="2"></li> </ol> <!-- 轮播项目 --> <div class="carousel-inner"> @foreach (var item in ViewBag.adList) { if (item == ViewBag.adList[0]) { <div class="item active"> <a href="@item.Url" title="@item.Title" target="_blank"> <img alt="First slide" src="@item.ImgUrl"> </a> <div class="carousel-caption"> <h3>@item.Title</h3> </div> </div> } else { <div class="item"> <a href="@item.Url" title="@item.Title" target="_blank"> <img alt="Second slide" src="@item.ImgUrl"> </a> <div class="carousel-caption"> <h3>@item.Title</h3> </div> </div> } } @*<div class="item active"> <a href="http://www.baidu.com" title="baidu" target="_blank"> <img alt="First slide" src="/upload/20161006/1.jpg"> </a> <div class="carousel-caption"> <h3>我是第一张幻灯片</h3> </div> </div> <div class="item"> <img alt="Second slide" src="/upload/20161006/2.jpg"> <div class="carousel-caption"> <h3>我是第二张幻灯片</h3> </div> </div> <div class="item"> <img alt="Third slide" src="/upload/20161006/3.jpg"> <div class="carousel-caption"> <h3>我是第三张幻灯片</h3> </div> </div>*@ </div> <!-- 项目切换按钮 --> <a class="left carousel-control" href="#myNiceCarousel" data-slide="prev"> <span class="icon icon-chevron-left"></span> </a> <a class="right carousel-control" href="#myNiceCarousel" data-slide="next"> <span class="icon icon-chevron-right"></span> </a> </div> </section> <section id="boke"> @foreach (var item in Model) { <div class="day"> <div class="dayTitle"> <a class="btn btn-primary">@item.bCreateTime.ToString("yyyy年MM月dd日")</a> </div> <div class="postTitle"> <a id="1" class="postTitle2" href="/blog/Detail/@item.bID">@item.btitle</a> </div> <div class="postCon"> <div class="c_b_p_desc"> 摘要:@item.bcontent...... <a href="/blog/Detail/@item.bID" class="btn btn-primary">阅读全文</a> </div> </div> <div class="postDesc"> <p>posted @@ @item.bCreateTime @item.bsubmitter 阅读(@item.btraffic) 评论(@item.bcommentNum) </p> </div> </div> } <footer class="pagination"> @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" }) @*@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>" })*@ @*@Html.Pager(Model, new PagerOptions { PageIndexParameterName = "pageindex", CurrentPagerItemTemplate = "<span class=\"current\">{0}</span>", DisabledPagerItemTemplate = "<span class=\"disabled\">{0}</span>", Id = "badoopager" })*@ </footer> </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); } }}
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!