前言
這次開發的博客主要功能或特點:
第一:可以兼容各終端,特別是手機端。
第二:到時會用到大量html5,炫啊。
第三:導入博客園的精華文章,並做分類。(不要封我)
第四:做個插件,任何網站上的技術文章都可以轉發收藏 到本博客。
所以打算寫個系類:《一步步搭建自己的博客》
- 一步步開發自己的博客 .NET版(1、頁面布局、blog遷移、數據加載)
- 一步步開發自己的博客 .NET版(2、評論功能)
- 一步步開發自己的博客 .NET版(3、注冊登錄功能)
- 一步步開發自己的博客 .NET版(4、文章發布功能)
- 一步步開發自己的博客 .NET版(5、搜索功能)
- 一步步開發自己的博客 .NET版(6、手機端的兼容)
演示地址:http://blog.haojima.net/ 群內共享源碼:469075305
博客做到這里 基本功能已經粗糙的完成了。注冊、登錄、發布、評論、博客遷移該有的都有了。這段時間內,差不多都是一個功能一個星期。說是一個星期,其實就周末兩天而已。鬼還沒天亮 就起來折騰,一做就是兩天 不動。說實話,真心累。不過欣慰的是,基本功能都出來了。
今天記錄下 文章發布功能的實現過程。
發布,首先得有個富文本編輯器。其它的編輯器 我沒了解過。聽說 百度的還不錯,就 稍微的研究了下。
百度編輯器
官網:http://ueditor.baidu.com/website/ 下載地址:http://ueditor.baidu.com/website/download.html
我這里用的是 開發版 
使用到自己的項目里面還是非常的簡單,不過這里需要注意的幾點。以下是問題記錄。
1.問題:
首先 我用的.net 4.5,把UBuilder直接放項目里面,運行報錯。沒細看報的什么錯。
解決方法:我直接把 目錄net->Bin文件夾 刪了。(可能是版本問題)
2.問題:
我們從http://ueditor.baidu.com/website/umeditor.html 官網演示地址可以看到 有如下 API。

我們通過 getContent()獲得 UBuilder 里的html內容 毫無問題。 通過setContent 加載內容時提示編輯器為空。
解決方法:當頁面加載完成時 賦值。
//頁面加載完成時 $(function () { var html = $(".hidden_data").val(); // 自定義的編輯器配置項,此處定義的配置項將覆蓋editor_config.js中的同名配置 var editorOption = { autoClearinitialContent: true, elementPathEnabled: true }; var editor_a = new baidu.editor.ui.Editor(editorOption); editor_a.render('editor'); editor_a.ready(function () { editor_a.setContent(html,false); //賦值給UEditor }); });
3.問題:
發布后的代碼樣式 無高亮。
解決方法:頁面加載完成是 執行高亮插件。
$(function () {
SyntaxHighlighter.highlight();
});
4.問題:
圖片上傳顯示失敗。(原因是改變了路徑)
解決方法:目錄net->config.json 打開配置文件。 "imageUrlPrefix": "/ueditor/net/", /* 圖片訪問路徑前綴 */ 改為UBuilder 放到項目的絕對路徑 如我的是放到了 文件夾Plug下 "imageUrlPrefix": "/Plug/ueditor/net/", /* 圖片訪問路徑前綴 */
5.問題:
這也不算問題,就是 我們不是專業的視頻網站,一般不允許傳視屏。
解決方法:可以配置 上傳文件的 格式 和大小。


基本上 我就做了這些處理。 這里還有個存在的問題 :就是我們在UBuilder 里面 復制過去的代碼 會自動給我去除div和樣式。所以,像我直接遷移的博客園文章內容,如果用UBuilder 打開 在保存的話 代碼就沒有了高亮 格式和亂了。(這點比較坑)。
標簽
我們在發布文章的時候,經常是需要 標簽和分類的。所在 這里最基本的功能 不能省。 
以圖為例。輸入標簽有兩種方式。第一:直接在文本框內輸入 以逗號 分割。第二種:勾選 復選框。
看似簡單的功能,其實不簡單。
首先 我們可以通過 勾選 復選框 來選擇 標簽,那么 我們就可以通過 取消 復選框 來 刪除 已經選好的標簽。那怎么實現呢?
選中的時候,先判斷 文本框內的最好一個字符是不是 , 如果不是 我們在 選中的時候 先 添加 逗號 然后 累加 我們選中的 復選框額值。
取消選中的時候,我們先 用逗號 分割 文本框 內的字符串,然后 如果有 我們要取消的 標簽 則刪除。
說了這么大堆 其實代碼實現也不多。
//點擊tag標簽時 function clik_tag(obj) { if ($(obj).is(":checked")) { //如果選中 var texttag = $(".text_tag"); if (texttag.val().length > 1 && texttag.val()[texttag.val().length - 1] != ",") { texttag.val(texttag.val() + ","); } var text_tag = texttag.val() + $(obj).val(); texttag.val(text_tag + ","); } else { //如果取消選中 var text_taglist = $(".text_tag").val().split(","); $(".text_tag").val(""); text_taglist.forEach(function (value, index) { if ($(obj).val() != value && value) $(".text_tag").val($(".text_tag").val() + value + ","); }); } }
這里還僅僅只是 前台頁面的顯示。 我們在后台也要判斷。 如果 這個標簽 已經存在 這直接查詢到 標簽id 如果不存在 先創建 標簽 然后去標簽id 和blog 關聯。
我們在前台 做點小的動作,分割 文本框內的所有標簽,如果存在 下面的 可選 標簽 則為舊的標簽 否則 是新的標簽。我們在傳入后台的時候 先進行下分類。這樣就免去了 我們在后台處理。(我的原則是,非安全性問題,能在前台處理 就在前台處理。)
//選擇的標簽 var oldtag = "", newtag = ""; var text_taglist = $(".text_tag").val().split(","); var chk_taglsit = new Array(); $(".chk_tag").each(function () { chk_taglsit[chk_taglsit.length] = $(this).val(); }); text_taglist.forEach(function (value, index) { if ($.inArray(value, chk_taglsit) >= 0) { oldtag += value + ","; } else { newtag += value + ","; } });
文章分類
文章分類 我們就沒有做 標簽那么靈活了。標簽 可以隨意貼上去。但是 分類 一般都是先 固定好。就像 分類:我們都是中國人。標簽:我們是程序員 ,明天可能又是測試員 大后天又能是美工、、沒辦法 所以 貼標簽 就要靈活多了。

邏輯不復雜 操作當然也要簡單。不就 是修改個值嘛,干嘛搞的那么 復雜。有的 實現方式需要幾個頁面 跳來跳去的。 我的實現是 點擊 修改 分類 直接變成 可編輯狀態。編輯完成后 光標點擊任意地方 就可以修改完成。 這樣 是不是 方便多了。
首先,我們點擊編輯的時候 用一個 input 的 text 控件 替換原來的 a標簽 ,並把值也傳過來。當 text 失去交點時 直接后台保存。並還原 為 a 標簽狀態。
這里 需要注意 重復點擊 編輯 不能 讓 再次替換。需要判斷下。
//新增類型 function addnewtype(obj) { var strhtml = "<div class='newtype'><input type='text' class='text_newtype' onblur='newtype_onblur(this);'/></div>"; var chi = $(obj).parents(".divtitle_chi"); if (chi.find(".newtype").length <= 0) { chi.append(strhtml).find(".text_newtype").focus(); } } function newtype_onblur(obj) { var value = $(obj).val(); if (!value) { $(obj).parents(".newtype").remove(); return; } $.post("@Url.RouteUrl("ControllerAction", new { controller = "Admin", action = "NewAddType" })", { "newtypename": value }, function (data) { if (ShowAjaxResult(data)) { } }); var newhtml = "<a>" + value + "</a>"; $(obj).parents(".newtype").removeClass("newtype").addClass("divtitle_chi").html(newhtml); } //修改 文章 類型 function edittype(obj) { $(obj).parents(".divtitle_chi").find(".text_newtype").unbind("blur"); if (!$(obj).next().hasClass("newtype")) { var value = $(obj).next().html().trim();//取得 文章類型 名稱 var typeid = $(obj).find(".hid_typeid").val(); //取得 文章類型id onblur='edittype_onblur(this);' var strhtml = "<div style='float:left' class='newtype'><input type='text' class='text_newtype' value='" + value + "' keyvalue='" + value + "' keyid='" + typeid + "' /></div>"; $(obj).next().css("display", "none"); // 隱藏原來顯示的文章類型 $(obj).after(strhtml).next().find(".text_newtype").focus().bind("blur", function () { edittype_onblur($(obj).parents(".divtitle_chi").find(".text_newtype")); }); //把 修改的文本元素添加 並獲得焦點 } else { edittype_onblur($(obj).after(strhtml).next().find(".text_newtype")); } } //鼠標移到目標的上方 function editover(obj) { $(obj).parents(".divtitle_chi").find(".text_newtype").unbind("blur"); //$(".testmess").html("unbind"); } //鼠標在目標的上方移動 function editmove(obj) { $(obj).parents(".divtitle_chi").find(".text_newtype").unbind("blur"); } //鼠標移出目標的上方 function editout(obj) { //$(".testmess").html("bind"); $(obj).parents(".divtitle_chi").find(".text_newtype").unbind("blur"); $(obj).parents(".divtitle_chi").find(".text_newtype").bind("blur", function () { // $(".testmess").html("bind"); edittype_onblur($(obj).parents(".divtitle_chi").find(".text_newtype")); }); } function edittype_onblur(obj) { var value = $(obj).val().trim(); //新的文章類型 var typeid = $(obj).attr("keyid").trim();//類型ID var oldvalue = $(obj).attr("keyvalue").trim();//舊的文章類型 if (!value || !typeid || value == oldvalue) { //1.如果值為空 2.如果類型id為空 3.如果沒有修改 則直接返回 $(obj).parents(".newtype").next().css("display", ""); $(obj).parents(".newtype").remove(); return; } $.post("@Url.RouteUrl("ControllerAction", new { controller = "Admin", action = "EditType" })", { "typename": value, "typeid": typeid }, function (data) { if (ShowAjaxResult(data)) { $(obj).parents(".newtype").next().remove(); var newhtml = "<a>" + value + "</a>"; var newtype = $(obj).parents(".newtype") newtype.after(newhtml); newtype.remove(); } else { $(obj).parents(".newtype").next().css("display", ""); $(obj).parents(".newtype").remove(); } });
最后看看效果圖:

總結
關於發布,其實要說的東西也不多。無非就是 用個富文本編輯器 編寫好內容 然后 更新到數據庫。然后 在更新的 時候 需要填寫 標簽 和 選擇分類。
這里還有一點 需要主要。asp.net 默認 是不允許 提交 標簽文本到服務器的。所以 我們這里 需要關閉 默認的 安全 驗證。
1.后台 訪問的 action 方法上 打上 [ValidateInput(false)] 的特性標簽。
2.在配置文件 配置(我用的是MVC是4.0 貌似必須要在配置文件配置)
<system.web > <httpRuntime requestValidationMode="2.0" / > </system.web >
演示地址:http://blog.haojima.net/Admin/Release/7 (需要登錄狀態 才能發布)
如果您對本篇文章感興趣,那就麻煩您點個贊,您的鼓勵將是我的動力。 當然您還可以加入QQ群:
討論。
如果您有更好的處理方式,希望不要吝嗇賜教。
一步步開發自己的博客 .NET版系列:http://www.cnblogs.com/zhaopei/tag/Hi-Blogs/

