ASP.NET MVC雕蟲小技 1-2

看到AnyTao和TerryLee分享的關於ASP.NET MVC使用和優化的技巧,不免手癢,也分享一下這一年多來ASP.NET MVC開發的積累。
其中未必是一些高效的技巧,但是的確是能解決問題,也未必有什麼高深的原理,只是我覺得值得分享。

1.Controller來控制HTML的Title

我想大部分朋友都有在Controller裏面指定Html頁面Title的需求。
我習慣於先寫使用的代碼再去完善其實現,而指定一個Title最方便的形式莫過於:
   1: public ActionResult Index(int id) {
   2:     var article=Db.GetArticle(id);//獲取數據庫裏的文章
   3:     Title=article.Name;
   4:     return View();
   5: }
當然,這段代碼是不能執行的,因爲Controller並沒有內建的Title屬性,不過沒關係,我們可以自定義一個:
   1: abstract public class MyBaseController : Controller {
   2:        public string Title {
   3:            set {
   4:                ViewData["Page_Title"] = value;
   5:            }
   6:        }
   7: }
然後將我們的Controller換爲這個MyBaseController,之後在Master中寫ViewData[“Page_Title”]的輸出就好了。
   1: <title><%=ViewData["Page_Title"] %></title>
OK,這個願意實現了。
當然做SEO的話Keyword和Description也可以這樣來搞。

2.ViewModel中傳遞Controller中定義的上下文

老趙十分推ViewModel於是我也做了不少這方面的實踐,發現的確不錯。但是有個問題,就是Controller中產生的上下文怎麼傳到View中去,比如說自定義的用戶信息,等一些非static的類型,而我又不想到View中再實例化一遍。
解決方法:ViewModel中另加一上下文屬性(在我和程序中這些上下文繼承於IContext接口,而在Controller中它的屬性是CHContext)
   1: public class HomeIndexViewModel {
   2:     public IContext Context { get; set; }//這個屬性就是解決它的方法
   3:     public string Message { get; set; }
   4: }
而我在Controller中:
   1: public ActionResult Index() {
   2:     HomeIndexViewModel model = new HomeIndexViewModel {
   3:         Context = CHContext,//這裏傳遞
   4:         Message="Welcome to ASP.NET MVC!"
   5:     };
   6:     return View(model);
   7: }
而View中:
   1: <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master"
   2: Inherits="System.Web.Mvc.ViewPage<HomeIndexViewModel>" %>
   3: <asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
   4:     Home Page
   5: </asp:Content>
   6: <asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
   7:     <h2><%= Html.Encode(Model.Message) %></h2>
   8: </asp:Content>
這樣我們就可以實現將Controller中產生的自定義上下文傳遞了。不過每個ViewModel都初始化一個IContext,未免太過頻繁, 也累人,於是進一步改進,我們利用作用在Controller上的Filter,在Controller的基類我們自定義的 MyBaseController中寫如下Filter,而實現這個功能則要所有的ViewModel繼承於一個類:MyBaseViewModel:
MyBaseViewModel與Model:
   1: public class MyBaseViewModel {
   2:     public IContext Context { get; set; }
   3: }
   4:  
   5: public class HomeIndexViewModel:MyBaseViewModel {
   6:     public string Message { get; set; }
   7: }
Controller與Filter
   1: abstract public class BaseController : Controller {
   2:     protected override void OnResultExecuting(ResultExecutingContext filterContext) {
   3:         var m = ViewData.Model as BaseViewModel;
   4:         if (m != null){
   5:             m.Context = CHContext;//在這裏初始化
   6:         }
   7:     }
   8: }
這回我們在Controller裏使用時就清爽了,不用再傳遞CHContext了。
 
如有意見歡迎提出
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章