一步步開發自己的博客 .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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM