利用MVC架構 實作我的部落格(一)

利用MVC架構 實作我的部落格(一)

程式看再多,沒有自己實作,還是不太踏實。

所以我打算花三個月(預計)的時間,自己做一個個人的部落格系統。

雖然到時不一定能上線,不過希望在實作的過程中,了解順便解決問題。

這個分類是紀錄我開發的過程中遇到的問題及解決的辦法,由於屬於練功性質,所以

架構跟程式方面可能會很凌亂,但是,就是學個經驗。

預計要有的功能:

  • 頁面:文章分類、文章瀏覽、搜尋、排序、標籤、以文找文。
  • 會員:註冊、登入、登出、收藏文章、回覆文章、留言。
  • 管理者:發表文章、文章管理、類別管理、會員管理、發送電子報、製作電子報。

第一個階段先把基本的功能弄出來,然後再來切版面,等雛型完成之後,再來做進階的功能。

第一天先做了登入以及註冊的功能…

拉出一個會員的table,然後建立一個 LINQ to SQL的dbml檔,在Model中建立一個資料夾Repository

專門放操作資料庫的類別。

先做了三個Controllers,分別是HomeController、MemberController、BaseController

BaseController是先建出來之後可以擴充用的,繼承Controller

 


public class BaseController : Controller
{
}

然後將其他的Controller繼承到BaseController

 


public class HomeController : BaseController
{
}

然後先做了註冊頁面,之前的文章有提到怎麼用Partial Class的方法做Server端的驗證

 

初學 ASP.NET MVC 學習筆記(七),所以這個部分做起來還滿順的。

大部分欄位都不能為空值

[Required(ErrorMessage = "請輸入信箱")]

像帳號長度不能超過12個字

[StringLength(12,ErrorMessage="長度不能超過12個字元")]

信箱有用規則驗算式

[RegularExpression(@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4})$", ErrorMessage = "請輸入正確的電子郵件位址,如:www@www.com")]

剩下的幾乎都是作苦工,一個屬性一個屬性慢慢設,設完就OK了。

在註冊的View上,生日的部分用JavaScript的套件選:

d9ce99ef5e6e4913964c56026b85c40f

詳細請參考Demo大的:

JSCalendar超好用的日期選擇器 For ASP.NET MVC

或是看原文:

http://www.dynarch.com/projects/calendar/

而我還沒把它包成Helper,所以目前在View上是這樣用:

 


 <%= Html.TextBoxFor(model => model.生日, new { @id="生日"})%>
          
            <button type="button" id="f_btn1">
                小日曆</button><br />

            <script type="text/javascript">                //<![CDATA[

                var cal = Calendar.setup({
                    date: 19800101,
                    onSelect: function(cal) { cal.hide() }
                });
                cal.manageFields("f_btn1", "生日", "%Y-%m-%d");

                //]]>
            </script>

然後在註冊頁為了防止用機器人瘋狂註冊,所以先做了一個簡單的驗證碼

f1828f267ceb418984f6da60e0aca768

做法是在Controller中件一個回傳FileResult的方法,然後用GDI將隨機亂數畫出來:


 public FileResult BMP()
        {
            string[] Code ={ "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",

                            "N",  "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",

                             "1", "2", "3", "4", "5", "6", "7", "8", "9" };

            string strRd = string.Empty;

            Random rd = new Random(); //unchecked((int)DateTime.Now.Ticks)
            
            Bitmap Bmp = new Bitmap(80, 25);  //建立實體圖檔並設定大小
            Graphics Gpi = Graphics.FromImage(Bmp);
            
            Font Font1 = new Font("Verdana", 14, FontStyle.Italic);
            for (int i = 0; i < 5; i++)       // 亂數產生驗證文字
            {
                strRd += Code[rd.Next(34)];
            }
            Pen PenLine = new Pen(Brushes.Red, 1);  //實體化筆刷並設定顏色、大小(畫X,Y軸用)
            Gpi.Clear(Color.Black);    //設定背景顏色
            Gpi.DrawLine(PenLine, 0, rd.Next(80), 90, rd.Next(25));
            Gpi.DrawString(strRd, Font1, Brushes.AntiqueWhite, 0, 0);

            for (int i = 0; i <= 25; i++)            //亂數產生霧點,擾亂機器人辨別
            {
                int RandPixelX = rd.Next(0, 80);
                int RandPixelY = rd.Next(0, 25);
                Bmp.SetPixel(RandPixelX, RandPixelY, Color.Pink);
            }
            Session["ValidateCode"] = strRd;        //將驗證碼存入Session以便稍後進行驗證
            MemoryStream s = new MemoryStream();
         
            Bmp.Save(s, System.Drawing.Imaging.ImageFormat.Gif);

            return File(s.GetBuffer(), "image/gif");
        }

之後在View上就可以用


<img src="<%=Url.Action("BMP")%>" id="bmp" />

將產生出來的驗證碼圖片Show在頁面上。

註冊要驗證時,只要將輸入驗證碼的input欄位的值跟存在Session中的亂數比對就行了。

註冊做完之後,就做登入。

登入我以前都是用Session來做登入判斷,跟把登入的會員資料都塞到Session中

但是.net有提供另外一種方便的登入方式,可以參考保哥的

概略解釋 Forms Authentication 的運作

登入的Action這樣寫:


登入密碼 = FormsAuthentication.HashPasswordForStoringInConfigFile(登入密碼, "SHA1");

            var m = t會員repository.Gett會員By帳號密碼(登入帳號, 登入密碼);

            if (m == null)
                return View();

            Session.RemoveAll();

            FormsAuthenticationTicket ticket = new FormsAuthenticationTicket
                (1, 
                m.ID.ToString(), 
                DateTime.Now, 
                DateTime.Now.AddMinutes(30), 
                false, 
                "Member", 
                FormsAuthentication.FormsCookiePath);

            string encTicket = FormsAuthentication.Encrypt(ticket);

            Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));

登出也很簡單,只要一行:

 


 public ActionResult LogOut()
        {
            FormsAuthentication.SignOut();
            return RedirectToAction("Index", "Home");
        }

如果某些頁面要登入的使用者才能看的話,只要在Action上加一句:

 


[Authorize]

   就行了。參考:ASP.NET MVC Form 驗證- demo小鋪

最後呢,在登入之後,我希望可以抓出一些使用者的資料,例如姓名,show在View上。

所以在View上這樣寫:


<%if (Request.IsAuthenticated)    //判斷使用者是否登入,true代表登入
  { %>
    哈囉,<%=SideHelper.Get會員姓名() %>  <%=Html.ActionLink("登出","LogOut","Member") %>  
<%}
  //如果是則用自己建立的Helper抓出使用者的名字
  //如果不是就出現登入的input
  else{ %>
    <%using(Html.BeginForm("LogIn","Member")) {%>
    <%=Html.LabelFor(model=>model.登入帳號) %>
    <%=Html.TextBox("登入帳號")%>
    <%=Html.LabelFor(model=>model.登入密碼) %>
    <%=Html.Password("登入密碼")%>
    <input type="submit" value="登入" />
    <%} %>
<%} %>

而Helper這樣寫:

 


namespace MyBlog.Helpers
{
    public static class SideHelper
    {
        public static string Get會員姓名()
        {     
            It會員Repository 會員 = new t會員Repository();
            return 會員.Get會員姓名(HttpContext.Current.User.Identity.Name);
         //HttpContext.Current.User.Identity.Name就是剛剛登入時塞進去的會員ID
         }
    }
}

Repository中的方法這樣寫:


 public string Get會員姓名(string id)
        {
            if (String.IsNullOrEmpty(id))
                return "";
            var m = (from p in db.t會員 where p.ID.Equals(id) select p).FirstOrDefault();
            if(m!=null){
                return m.暱稱;
            }
            return "";
        }

 

完成之後,未登入時是看到

b4fcb73292f142c8b4ff33d25cbb6bfd

登入之後就是:

08a83628dcee4406bbb14a2adb009727

 

 

收工。第一天做完這些,大概花了三個鐘頭。