zoukankan      html  css  js  c++  java
  • 一步步开发自己的博客 .NET版(1、基本显示)

    前言   

          我们每个猿都有一个搭建自己独立博客的梦,我也不例外。以前想 现在想 以后也想。之所以一直迟迟没有着手,是因为难以跨出第一步。每次心里想着,等我以后技术好了再说,然后就没有然后了。以前用过wordpress,虽然插件很多,不过有时候想改改自己想要的效果很难,因为 我压根就不会php。也看过.net的一些开源博客,代码量多,看得头晕,没那个耐心。

          再说,别人的始终是别人的。得鱼不如得渔。与其花时间去研究php还不如自己写个.net版的。有人说博客园已经很好了啊,我承认确实,而且还可以后台定制自己想要的样式和js。不过始终还是不如自己开发的来得随心所欲。最重要自己开发还可以当作练手 对一个网站的各环节  做一次练习,用以发现自己的不足,并加以提升。那我以后的博客写哪里呢?当然还是会继续发博客园,谁叫这里人气旺呢。

        这次开发的博客主要功能或特点:
        第一:可以兼容各终端,特别是手机端。
        第二:到时会用到大量html5,炫啊。
        第三:导入博客园的精华文章,并做分类。(不要封我)
        第四:做个插件,任何网站上的技术文章都可以转发收藏 到本博客。

    所以打算写个系类:《一步步搭建自己的博客

    关于域名和空间

          在以前我们学C#的想要搭一个免费的博客,要不只能用国外的免费空间要么在linux下用php。用起来都是各种坑,网速各种卡。然后,现在我们学C#的时代来了,这里要感谢阿里云(免费主机)。当然域名还是要自己买的。万网 和 新网 可以对比下  哪里便宜买哪里,都可以用。(注意:最好买 .com .net .cc .org 因为有些域名不能在阿里备案)。买好域名之后 然后就是备案了,备案也没什么复杂的,阿里自动备案。中间除了 找阿里 要一块免费的布 照个相 寄过去,就是等了,其他的什么也不用做。大概半个月的样子吧。建议  买域名的时候最好一次性买久一点,不然后期再续费要比第一次买贵。(如果您实在不想花这个钱,这个我最后给您支个招吧,你申请好免费的主机后,你把主机ip给我,我免费给你二级域名。谁叫我是活雷锋)

    开发环境

          域名和主机都搞定以后,就开始选择开发环境了。我选的是 vs2013 mvc4 ef6.0 mssql   。

    博客迁移

          然后就是博客迁移,之前也老想着搭建博客,可一直没有行动。这就是从0到1 的难。只要你走出了第一步 后面就 顺畅得多了。那么 我们搭博客 没有测试数据 总还是感觉没什么动力。所以,我就写了个程序,把我在博客园发表的文章扒过去。

          那么我们需要哪些数据呢?现在大概想到的有:博客正文、tag标签、文章分类、创建时间、博客标题

          好了,那我们就正式开始扒吧。(可以参考我以前的博客备份小工具3

          首先是从/mvc/blog/sidecolumn.aspx页面取得 文章分类。然后根据 每个类型 的链接 取得这个类型下的所有文章。然后在取正文的时候发现 文章所属tag标签和分类是异步的到页面的, http://www.cnblogs.com/mvc/blog/CategoriesTags.aspx?blogApp=用户名&postId=文章id。(也许博客园有api,我也没去看没去找。)

    1.首先建一个实体数据模型

    我这里采用的是 model first(之前搞错概念了,谢谢园友指正) 。这里要说明的是 tag标签和文章是多对多的关系,文章类型和文章也是多对多的关系。

    2.然后根据模型生成数据库

           个人觉得这里非常爽,自动帮我建好了 主外键  和索引,免除了我们自己手动去在数据库里面建。

    3.从博客园扒数据

           模型和数据库建好了,那么我们现在就开始迁移吧~下面是全部代码,其中有存数据库的部分可以自己改改。

    /// <summary>
            /// 根据用户导入cnblog数据
            /// </summary>
            /// <param name="userName"></param>
            /// <returns></returns>
            public string Import(string userName, string iszf = "false")
            {
                int blosNumber = 0;
                JavaScriptSerializer jss = new JavaScriptSerializer();
                string url = "http://www.cnblogs.com/" + userName + @"/mvc/blog/sidecolumn.aspx";
                HtmlAgilityPack.HtmlWeb htmlweb = new HtmlAgilityPack.HtmlWeb();
                var docment = htmlweb.Load(url);
                string userid = GetCnblogUserId(userName);
                var liS = docment.DocumentNode.SelectNodes("//*[@id='sidebar_categories']/div[1]/ul/li");
                foreach (var item in liS)
                {
                    var tXPath = item.XPath;
                    var href = item.SelectSingleNode(tXPath + "/a").Attributes["href"].Value;
                    var blogtype = htmlweb.Load(href);
                    //var entrylistItem = blogtype.DocumentNode.SelectNodes("//*[@id='mainContent']/div/div[2]/div[@class='entrylistItem']");
                    var entrylistItem = blogtype.DocumentNode.SelectNodes("//div[@class='entrylistItem']");
                    if (null == entrylistItem)//做兼容
                        entrylistItem = blogtype.DocumentNode.SelectNodes("//div[@class='post post-list-item']"); //    
                    if (null == entrylistItem)
                    {
                        continue;
                    }
                    foreach (var typeitem in entrylistItem)
                    {
                        var typeitemXPath = typeitem.XPath;
                        var typeitemhrefObj = typeitem.SelectSingleNode(typeitemXPath + "/div/a");
                        if (null == typeitemhrefObj) //做兼容
                            typeitemhrefObj = typeitem.SelectSingleNode(typeitemXPath + "/h2/a");
                        var typeitemhref = typeitemhrefObj.Attributes["href"].Value;
                        if (IsAreBlog(typeitemhref))
                            continue;//说明这篇文章已经备份过了的
                        var bloghtml = htmlweb.Load(typeitemhref);
                        var blogcontextobj = bloghtml.DocumentNode.SelectSingleNode("//*[@id='cnblogs_post_body']");//.InnerHtml;
                        if (blogcontextobj == null) continue;//有可能是加密文章
                        var blogcontext = blogcontextobj.InnerHtml;
                        var blogtitle = bloghtml.DocumentNode.SelectSingleNode("//*[@id='cb_post_title_url']").InnerText;
                        var blogurl = bloghtml.DocumentNode.SelectSingleNode("//*[@id='cb_post_title_url']").Attributes["href"].Value;
                        var blogtypetagurl = "http://www.cnblogs.com/mvc/blog/CategoriesTags.aspx?blogApp=" + userName + "&blogId=" + userid + "    =" +
                            typeitemhref.Substring(typeitemhref.LastIndexOf('/') + 1, typeitemhref.LastIndexOf('.') - typeitemhref.LastIndexOf('/') - 1);
                        var blogtag = Blogs.Common.Helper.MyHtmlHelper.GetRequest(blogtypetagurl);
                        var jsonobj = jss.Deserialize<Dictionary<string, string>>(blogtag);
                        if (null == jsonobj)
                            continue;//如果没有 则返回  (这里只能去 数字.html  不能取那种自定义的url)
                        var tagSplit = jsonobj["Tags"].Split(',');
                        var blogtagid = new List<int>();
                        for (int i = 0; i < tagSplit.Length; i++)
                        {
                            if (tagSplit[i].Length >= 1 && tagSplit[i].LastIndexOf('<') >= 1)
                            {
                                var blogtagname = tagSplit[i].Substring(tagSplit[i].IndexOf('>') + 1, tagSplit[i].LastIndexOf('<') - tagSplit[i].IndexOf('>') - 1);
                                blogtagid.Add(this.GetTagId(blogtagname, userName));
                            }
                        }
                        var categoriesSplit = jsonobj["Categories"].Split(',');
                        var blogtypeid = new List<int>();
                        for (int i = 0; i < categoriesSplit.Length; i++)
                        {
                            if (categoriesSplit[i].Length >= 1 && categoriesSplit[i].LastIndexOf('<') >= 1)
                            {
                                var blogtypename = categoriesSplit[i].Substring(categoriesSplit[i].IndexOf('>') + 1, categoriesSplit[i].LastIndexOf('<') - categoriesSplit[i].IndexOf('>') - 1);
                                blogtypeid.Add(this.GetTypeId(blogtypename, userName));
                            }
                        }
                        var blogtimeobj = bloghtml.DocumentNode.SelectSingleNode("//*[@id='post-date']");
                        var blogtime = "";
                        if (null != blogtimeobj)
                            blogtime = blogtimeobj.InnerText;
    
    
                        BlogsBLL blog = new BlogsBLL();
                        var myBlogTags = new BlogTagsBLL().GetList(t => blogtagid.Contains(t.Id), isAsNoTracking: false).ToList();//.ToList();                                        
    
                        var myBlogTypes = new BLL.BlogTypesBLL().GetList(t => blogtypeid.Contains(t.Id), isAsNoTracking: false).ToList();//.ToList();
                        try
                        {
                            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();
                            blosNumber++;
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                }
                if (blosNumber > 0)
                    return "成功导入" + blosNumber + "篇Blog";
                return "ok";
            }
    
            private int GetTagId(string tagname, string userName)
            {
                BlogTagsBLL blogtag = new BlogTagsBLL();
                try
                {
                    var blogtagmode = blogtag.GetList(t => t.TagName == tagname);
                    if (blogtagmode.Count() >= 1)
                        return blogtagmode.FirstOrDefault().Id;
                    else
                    {
                        blogtag.Add(new ModelDB.BlogTags()
                        {
                            TagName = tagname,
                            IsDel = false,
                            UsersId = GetUserId(userName)
                        });
                        blogtag.save();
                        return GetTagId(tagname, userName);
                    }
                }
                catch (Exception)
                {
                    return -1;
                }
            }
    
    
            private int GetTypeId(string typename, string userName)
            {
                BlogTypesBLL blogtype = new BlogTypesBLL();
                var blogtagmode = blogtype.GetList(t => t.TypeName == typename);
                if (blogtagmode.Count() >= 1)
                    return blogtagmode.FirstOrDefault().Id;
                else
                {
                    blogtype.Add(new ModelDB.BlogTypes()
                    {
                        TypeName = typename,
                        CreateTime = DateTime.Now,
                        IsDel = false,
                        UsersId = GetUserId(userName)
                    });
                    blogtype.save();
                    return GetTypeId(typename, userName);
                }
            }
    
            /// <summary>
            /// 获取haojima用户id
            /// </summary>
            /// <param name="userName"></param>
            /// <returns></returns>
            private int GetUserId(string userName)
            {
                BlogUsersBLL user = new BlogUsersBLL();
                var blogtagmode = user.GetList(t => t.UserName == userName);
                if (blogtagmode.Count() >= 1)
                    return blogtagmode.FirstOrDefault().Id;
                else
                {
                    user.Add(new ModelDB.BlogUsers()
                    {
                        UserName = userName,
                        IsDel = false,
                        UserPass = "admin",
                        UserNickname = userName
                    });
                    user.save();
                    return GetUserId(userName);
                }
            }
    
            /// <summary>
            /// 检查 这个 url地址 是否被添加过
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            private bool IsAreBlog(string url)
            {
                BLL.BlogsBLL blog = new BLL.BlogsBLL();
                var blogs = blog.GetList(t => t.BlogUrl == url);
                return blogs.Count() >= 1;
            }
    
            /// <summary>
            /// 获取cnblog用户id
            /// </summary>
            /// <param name="url"></param>
            /// <returns></returns>
            private string GetCnblogUserId(string url)
            {
                HtmlAgilityPack.HtmlWeb htmlweb = new HtmlAgilityPack.HtmlWeb();
                var docment = htmlweb.Load("http://www.cnblogs.com/" + url);
                var list = docment.DocumentNode.SelectNodes("//link[@rel='stylesheet']");
                foreach (var item in list)
                {
                    if (null != item.Attributes && item.Attributes.Contains("href"))
                    {
                        var href = item.Attributes["href"].Value;
                        href = href.Substring(href.LastIndexOf("/") + 1, href.IndexOf(".") - href.LastIndexOf("/") - 1);
                        int userid = -1;
                        if (int.TryParse(href, out userid))
                            return userid.ToString();
                    }
                }
                return "";
            }
    View Code

    页面布局

          关于页面布局 ,怎样简单怎样来。我是分成了 头、尾、中间。中间二八分。这个不重要,现在暂时这么遭。以后再考虑 多终端的兼容。

    数据加载

           现在数据都已经迁移过来的,需要展示在我们自己搭建的博客,我想对于大家来书应该没什么难度。从学编程开始,老师就教我们 增删改查。只是美与丑的问题。

           这里有一点要注意,因为正文内容保存到数据库的都是html代码,而我们要在首页展示文章列表只显示小部分内容,那怎么截取字符串呢?你不能保证刚好是在html标签结尾后截取啊。我这里用到了HtmlAgilityPack取InnerText 的属性。就像jqeruy中 .html() 和 .text()区别,如果截图断了html标签 显示 将会很混乱。       

    最后总结

          这个博客我也才刚开始做,现有也仅仅只是实现了博客的展示功能,连分页都还没有去实现。所以本系列博客更新会比较慢。我也需要边做边学边更新,工作中还没用过MVC。

    到最后等我做完了,我会放git上开源,到时候大家有兴趣的可以一起来完善和定制自己想要的效果。

           说了这么多来张效果图吧。

           

         

    如果您对本篇文章感兴趣,那就麻烦您点个赞,您的鼓励将是我的动力。 当然您还可以加入QQ群:嗨 博客讨论。

    演示地址:http://blog.haojima.net/

    原文链接:http://www.cnblogs.com/zhaopei/p/4737958.html 

    一步步开发自己的博客 .NET版系列:http://www.cnblogs.com/zhaopei/tag/Hi-Blogs/

    开源地址:http://git.oschina.net/zhaopeiym/Hi-Blogs

  • 相关阅读:
    CF 142B Tprimes
    CF 231A Team
    poj 2001 Shortest Prefixes ——字典树入门
    hdu 1039 Easier Done Than Said?
    poj 2528 Mayor's posters
    hdu 1061 Rightmost Digit
    poj 2503 Babelfish
    CF271 A. Beautiful Year
    poj 2752
    CF271 B. Prime Matrix
  • 原文地址:https://www.cnblogs.com/zhaopei/p/4737958.html
Copyright © 2011-2022 走看看