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


    《一步步搭建自己的博客》 源码地址 :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,否则保留追究法律责任的权利 

  • 相关阅读:
    SpringBoot+CXF下Https调用webservice跳过安全证书的配置
    程序员的长安十二时辰:Java实现从Google oauth2.0认证调用谷歌内部api
    springboot集成activiti6.0多数据源的配置
    activiti工作流委托功能的设计和实现
    vue.js带复选框表单的增删改查
    bootstrap-treeview后台Json数据的封装及前台的显示
    你好,Spring!
    超大份线程池,干杯,兄弟!陆
    嗯!这篇多线程不错!伍
    是兄弟!就来看这篇多线程!叁
  • 原文地址:https://www.cnblogs.com/izhiniao/p/4776999.html
Copyright © 2020-2023  润新知