其实Wordpress 已经做得很好了,DoNet也有不少成熟的系统,还有很多大型的CMS,可我就是不想改别人的代码,也想按照自己的意愿设计。个人是对做.net 工作的,对比了下java和php 确实更喜欢.net也发现它不少好处,所以当然是用.net 开发的。之前是简单的asp.net页面,后缀也是aspx,很久后用asp.net mvc进行了重构。
先看下后台的图
后台是用 easyUI 开发的界面,从网上找的基本框架。这个后台其实是运行在本地的,数据库也是在本地,文件也是上传到本地的,因为自己网络环境太差,而且这样做也不用服务器受到攻击,因为所有数据和文件全部在本地。之后肯定是需要把文件和和数据库同步到服务器上,为此我做了一些小工具。
数据库同步
之后要把朋友的博客搬家,于是做了一个简单的分析采集工具
这些工具有时间会分享出来。
博客主站和后台管理、静态文件、用户系统我是设计成独立的站点的,这样能更好的分层架构,之后用了一段时间百度云存储,最后还是迁移到阿里云存储了,主要存储图片文件,实在受不了上传文件直接传到当前站点里,导致很臃肿。
整体架构
用了自己的简单ORM框架,因为EF用得不是很好,基本的作用就是单表新增修改删除,有些复杂的就写sql来操作,博客的主页查询是用函数和存储过程写在数据库中的。
Blogs.UI.Main是博客的主页,Blogs.UI.Manage是后台管理,运行在本地,Blogs.UI.Server是对外提供一些服务,比如安卓调用接口,暂时没用到。
Blogs.UI.Main 是MVC开发的,暂时有2套主题都是从网上找的,自己不会做前端。
控制器和模型
套UI看起来不算难,不过做一套UI还是要费不少时间
总之,做做停停,开发了很久用了很多时间。自己看起来也不是太难的东西,前台界面元素也不多。
看看2套主题效果吧,自己不会做前台就是痛苦。
另外一套
这2个站的代码完全一样,就是连接的数据库不一样。本来主题名是存入到数据库的,不过每次都要读效率不好,做了个xml文件,切换主题也很简单。
伪静态是用的mvc的自定义路由。
这个路由表设计为10分钟再刷新一次,为了效率
首页等一些页面也做了静态页缓存机制,简单说就是用mvc的机制生成静态页然后存到本地文件,如果访问页面查找有静态文件就直接展示静态页,避免了查询数据库等复杂逻辑,当然按照自己设定的一定时间比如10分钟会再生成一次静态页。
CompressAttribute 属性是是否压缩页面的,比如去掉换行等。
创建静态页代码
/// <summary> /// 创建静态页 /// </summary> /// <param name="controller"></param> /// <param name="viewName"></param> /// <param name="GetModelMethod">获取模型的方法</param> /// <param name="folderPath">静态页保存的路径</param> /// <param name="indexName">如果路径为/ 使用的文件名 如index.html</param> /// <returns></returns> public static ActionResult CreateStaticHtml(Controller controller, string viewName, Func<object> GetModelMethod, string folderPath, string indexName) { folderPath = folderPath.TrimEnd('/'); //是否启用静态页 bool isUseStaticHtml = (System.Configuration.ConfigurationManager.AppSettings["isUseStaticHtml"] == "true"); if (isUseStaticHtml) { string absPath = controller.Request.Url.AbsolutePath.Substring(controller.Request.Url.AbsolutePath.LastIndexOf("/") + 1); if (absPath == "") { absPath = indexName; } //如果目录不存在则创建 if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } string s = Directory.GetFiles(folderPath, "*-" + absPath).FirstOrDefault(); string filePath = String.Empty; //如果强制刷新 bool isRefresh = File.Exists(controller.HttpContext.Server.MapPath("~/App_Data/refresh.txt")); if (s != null && isRefresh == false) { long updateDate = Convert.ToInt64(Regex.Match(Path.GetFileName(s), "(.*)-" + absPath).Groups[1].Value); filePath = folderPath + "/" + updateDate + "-" + absPath; //默认刷新时间30 分钟 int refresh = 1800; string staticHtmlRefreshTimeout = System.Configuration.ConfigurationManager.AppSettings["staticHtmlRefreshTimeout"]; if (!String.IsNullOrEmpty(staticHtmlRefreshTimeout)) { refresh = Convert.ToInt32(staticHtmlRefreshTimeout); } //如果没有超过刷新时间 则从静态页读取 if (Convert.ToInt64(DateTime.Now.ToString("yyyyMMddHHmmss")) - updateDate < refresh) { string content = System.IO.File.ReadAllText(filePath, System.Text.Encoding.UTF8); return new ContentResult { Content = content }; } } filePath = folderPath + "/" + DateTime.Now.ToString("yyyyMMddHHmmss") + "-" + absPath; //删除以前生成的文件 if (s != null) { System.IO.File.Delete(s); } object obj = GetModelMethod.Invoke(); string html = Blogs.Common.ControllerHelper.RenderPartialViewToString(controller, viewName, obj); TextWriter w = new StreamWriter(filePath, false, System.Text.Encoding.UTF8, 4096); w.Write(html); w.Close(); return new ContentResult { Content = html }; } return null; }
服务器在香港,大陆访问确实可能慢些,先写到这了。