学习 《一步步搭建自己的博客》 第一版 边理解边记录

《一步步搭建自己的博客》 源码地址 :http://www.cnblogs.com/zhaopei/p/4737958.html   如果你也在学习,请私密或者留言,欢迎一切学习总结,分享!

 

首先我从导数据开始  -------  一切的源头 

AdminHelperController  index  view中的  :

   $.post("http://" + location.host + "/" + $("#iszf").attr("checked") + "/AdminHelper/butOk/" + $("#user").val(),

 标识  post的地址 : Request URL:http://localhost:49532/checked/AdminHelper/butOk/zhaopei   //这里的checked参数 ?

 注意 :

location.host 包含端口,比如是 127.0.0.1:81。如果端口是 80,那么就没有端口,就是 127.0.0.1。

location.hostname 不包含端口,比如是 127.0.0.1。

 

根据上面的代码 : 发现 post执行的 Controller 与 Action 分别是 : AdminHelper/butOk  对应的 路由应该是 :

//第四种情况:以 域名 + 用户名
            routes.MapRoute(
             name: "UserIndex",
             url: "{name}/{controller}/{action}/{id}",
             defaults: new { action = "UserBlogList", controller = "UserBlog", id = UrlParameter.Optional }
          );

 然而 butOk 内部调用的是 :Import方法 ,这个方法比较复杂待我好好研读! 

进入 Import 方法后发现 博主拼接了  url  这里以我自己的博客为例 :http://www.cnblogs.com/izhiniao/mvc/blog/sidecolumn.aspx 感兴趣的可以单机进去看看 ,可以帮助理解! 然而Import中结尾包含 下面这段代码 ,我想应该是把数据 存如数据库

var modelMyBlogs = new ModelDB.Blogs()
                        {
                            BlogContent = blogcontext,
                            BlogCreateTime = blogtime,
                            BlogTitle = blogtitle,
                            BlogUrl = blogurl,
                            IsDel = false,
                            BlogTags = myBlogTags,
                            BlogTypes = myBlogTypes,
                            UsersId = GetUserId(userName),
                            BlogForUrl = blogurl,
                            IsForwarding = iszf == "checked"
                        };
                        blog.Add(modelMyBlogs);
                        blog.save();

 那么 下面 的这段代码 背后隐藏写什么呢 ? 我先来个猜想 , 后续联系博主待证实......? 

 blog.Add(modelMyBlogs);

  

         猜想 :F12 过去  

           

         这里我标出的“需要注意”  主要是Model1Container 是数据库的网关类 ,crud都是统一入口, 继承自 DbContext 这里有篇博客介绍了 ObjectContext

         DbContext 和ObjectContext两者的区别 : ObjectContext是一种模型优先的开发模式,DbContext是代码优先的开发模式 , 还可以相互转换!

 最后 save()是这样构造的 :这里才进行数据库操作(顺便提提 上面的 add(model)是生存sql语句

 public int save()
        {
            return db.SaveChanges();
        }

  这个类暂时解说到这里,对HtmlAgilityPack的理解 自行找资料(不过后期我会开博客写写HtmlAgilityPack) , 其实国人开发的  Jumony 更好用 

 

 

 

2015-09-06  今天看看数据库 , 把数据库关系给大概理清晰

有三个暂时未知干嘛,别的根据数据很快就能看出来,这里我直接上图

 

 

 

既然前面我们把数据给写入到数据库了,那么接下来我就去看看 博主是怎么把数据给显示出来的 ...

那么我们首先来从 Blogs.Web 开始 往数据方向一步一步去推导 ...

HomeController 下的 Index()  就是 博客view对应的action 方法 , 这个方法 里面第一行代码是  BLL.BlogsBLL blog = new BLL.BlogsBLL(); 创建了一个逻辑Blogs类,

具体怎么处理 , 背后隐藏了些什么 (这是三层中的逻辑层,待我稍后细细分析) , 我先看看 下面的代码 :

 var bloglist = blog.GetList(t => t.Id < 50)//我本人对Lamda表达式不熟练,到时候我单独写一篇关于lamda表达式的文章,在对这里做个解析
                .Select(t => new
                {
                    Id = t.Id,
                    BlogTitle = t.BlogTitle,
                    BlogContent = t.BlogContent,
                    UserName = t.Users.UserName,
                    UserNickname = t.Users.UserNickname,
                    BlogCreateTime = t.BlogCreateTime
                })
                .ToList()
                .Select(t => new ModelDB.Blogs()
                {
                    Id = t.Id,
                    BlogTitle = t.BlogTitle,
                    BlogContent = MyHtmlHelper.GetHtmlText(t.BlogContent),
                    BlogCreateTime = t.BlogCreateTime,
                    Users = new ModelDB.BlogUsers()
                    {
                        UserName = t.UserName,
                        UserNickname = t.UserNickname
                    },
                }).ToList();

  

 这里的  bloglist 就是博客文章清单 ,然后把这个清单放入 数据字典中 供view 强类型解析

  Dictionary<string, object> dic = new Dictionary<string, object>();

  这里的  CacheData.GetUserInfo() 是获得用户信息,博主这里用的缓存(本人水平有限,暂时还没有设计到缓存,以后在细说缓存)

对于view中的代码我就解析几个有意思的地方

     <a href="~/@(blog.Users.UserName)/@(blog.Id).html">@blog.BlogTitle</a>

  这个 条 语句生成的html代码是 :  <a href="/zhaopei/12.html">一步步开发自己的博客 .NET版(3、注册登录功能)</a>

 

所以它对应的 路由大概是  :

   //第一种情况:以 域名 + 用户名 + id + html 后缀组合(默认控制器)
            routes.MapRoute(
               name: "UserPage",
               url: "{name}/{id}.html/{controller}/{action}",
               defaults: new { action = "UserBlog", controller = "UserBlog", name = "zhaopei", id = 1 }
           );

对于获取所有博客的用户信息 做的缓存 我这里分析下   :

 /// <summary>
        /// 获取所有博客的用户信息
        /// </summary>
        /// <param name="newCache">是否重新获取</param>
        /// <returns></returns>
        public static List<BlogUsers> GetUserInfo(bool newCache = false)
        {
            if (null == HttpRuntime.Cache["UserInfo"] || newCache)
            {
                BLL.BlogUsersBLL user = new BlogUsersBLL();
                HttpRuntime.Cache["UserInfo"] = user.GetList(t => true).ToList();
            }
            return (List<BlogUsers>)HttpRuntime.Cache["UserInfo"];
        }

  根据代码可以看出 首先判断缓存是否存在和是否从新获得缓存 , 如果不为空 我们就返回缓存-----那么问题又来了,我们第一次的缓存从那里获得呢 ?

 这里只能待 博主来回答了  ,我暂时不得而知 。。。。(这个问题待我今天从新看 , 秒懂 ,昨天这么就没看出来呢 )

 当 null == HttpRuntime.Cache["UserInfo"] 时  就获取啊 (这不就是第一次获取吗 , 自己SB ^_^ ) HttpRuntime.Cache["UserInfo"] = user.GetList(t => true).ToList();

 下面这段代码主要是 实现内容过长而隐藏 ...

   @Html.Raw(blog.BlogContent.Substring(0, con_length))

 

2.下面就是用户单击 博客标题后进入博客内容的实现 UserBlogController /UserBlog:

 public ActionResult UserBlog(string name, int id)
        {
            BLL.BlogsBLL blog = new BLL.BlogsBLL();
            var blogobj = blog.GetList(t => t.Id == id && t.Users.UserName == name).FirstOrDefault();

            //这里看 能不能只查询一次
            var blogNext = blog.GetList(t => t.Id > id && t.Users.UserName == name).OrderBy(t => t.Id).FirstOrDefault();
            var blogLast = blog.GetList(t => t.Id < id && t.Users.UserName == name).OrderBy(t => t.Id).FirstOrDefault();

            var commentList = blogobj.BlogComment.ToList();

            Dictionary<string, object> dic = new Dictionary<string, object>();
            dic.Add("blog", blogobj);
            dic.Add("blogNext", blogNext);
            dic.Add("blogLast", blogLast);
            dic.Add("commentList", commentList);//对应的评论
            dic.Add("contentBlogType", blogobj.BlogTypes.ToList());
            dic.Add("contentBlogTag", blogobj.BlogTags.ToList());

            SetDic(dic, name);
            return View(dic);
        }

  看到这段代码我就理解了,就不需要进行详细的讲解,如果你不懂,可以在下面进行留言,写明情况我有时间会回复你!

  弄到这里我本来想看看博主的这个博客系统 的资源是怎么放置的 , 第一版发现 图片链接都是直接调用 博客园的 链接

对于标签问题(这里只截了部分代码)

 <a href="~/@(blogName)/GetTagBlogs/@(item.Id).html" >

 发现匹配的 路由是 : 

 //第二种情况:以 域名 + 用户名 + action  + id + html 后缀组合
            routes.MapRoute(
             name: "UserTagOrType",
             url: "{name}/{action}/{id}.html/{controller}",
             defaults: new { action = "UserBlogList", controller = "UserBlog" }
          );

  

 今天就解读到这里 , 下次解读异常处理!

 

 

现在开始继续读代码 : 这里先把昨天的遗留的问题给提下 , 已经解决 , 楼下的 游戏世界 也问了 , 由于博主时间有限 , 我就自己在认真的找了下 , 秒懂 , 上面的红体部分给出解析

那么接下来我就 研读下异常处理吧 , 因为我没自己搭建过项目 , 所以不懂, 就从博主的开始 ,至于他的处理方式好不好,我在文章中不做什么解析(我自己没这能力去评价,不过你觉得你的方法好,可以指点下我,小弟在这谢谢您了

 

        /// 全局未处理异常捕获
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Application_Error(object sender, EventArgs e)
        {
            #region 异常注释
            Exception ex = Server.GetLastError().GetBaseException();
            ErrLog.ErrLogSave(ex);
            string strErr = ErrLog.GetExceptionInfo(ex);
            //处理完及时清理异常 
            Server.ClearError();
            #endregion

            //Application_Error 里不能访问和操作 session为null 20150205            
            //HttpContext.Current.Session
            //Context.Session

            #region 跳转至出错页面
            //跳转至出错页面 
            //Server.Transfer("~/html/500.aspx");
            //注意:如果是ajax的请求 是不能 Response.Redirect 重定向的
            string sheader = Context.Request.Headers["X-Requested-With"];
            bool isAjax = (sheader != null && sheader == "XMLHttpRequest") ? true : false;
            if (isAjax)
            {
                HttpContext.Current.Response.Write(
              new CustomModel.JSData()
              {
                  State = CustomModel.EnumState.异常或Session超时,
                  JSurl = "/html/500.html?err=" + Microsoft.JScript.GlobalObject.escape(strErr)//System.Web.HttpUtility.UrlEncode(strErr)
              }.ToJson());
            }
            else
                Response.Redirect("~/html/500.html?err=" + Microsoft.JScript.GlobalObject.escape(strErr));
            #endregion
        }

按F12 走了个大体流程我觉得有必要专门写一篇 关于 异常在这个博客系统中的应用 !

 那么本篇文章到此结束 , 如果你感兴趣请继续阅读下篇 http://www.cnblogs.com/izhiniao/p/4790149.html

 

     本文以学习、研究和分享为主,版权归作者和博客园共有,未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接 http://www.cnblogs.com/izhiniao,否则保留追究法律责任的权利 

 

posted on 2015-09-01 21:54  知鸟  阅读(679)  评论(8编辑  收藏  举报