標籤:style blog http color 使用 os
原帖地址:http://www.cnblogs.com/QLeelulu/archive/2008/10/04/1303913.html
view在MVC模式中與使用者進行最直接的接觸,它負責資料的呈現。這裡要注意一點就是,view只是負責資料的呈現,所以我們應該要盡量讓view中不涉及商務邏輯的處理。
我們來添加一個Blog首頁的view。在安裝了ASP.NET MVC後,我們在添加新項目的時候可以看到有MVC的view模板:
註:如果你的是中文版的VS,安裝完後可能會出現找不到這個模板的現象,你可以參考在中文版VS 08中安裝MVC這篇文章設定一下。
其中MVC View Content Page是有主版頁面的。我們在Views/Home目錄下添加一個MVC View Content Page,並選擇我們Views/Shared目錄下的Site.Master主版頁面:
public partial class Index : ViewPage
{
}
ASP.NET MVC預設是使用WebForm來作為view的。所以我們看到建立的aspx頁面繼承自ViewPage,如果使用aspx頁面作為ASP.NET MVC的視圖引擎,則所有的aspx頁面都必須繼承自ViewPage。我們再看一下ViewPage:
我們看到ViewPage繼承自ASP.NET WebForm的Page頁,還實現了IViewDataContainer介面,同時還提供了一些Helper類的執行個體。我們可以使用ViewData來從Controller中往view頁面中傳遞資料。下面我們在HomeController中的Index Action中取出Posts列表,然後在View中顯示。我們先在Controller中取出資料,前面說過,為了方便,我們會直接使用BlogEngine的Model層來作為我們這個4mvcBlog的Model。所以我們的代碼如下:
public ActionResult Index(int? id)
{
ViewData["Title"]= BlogSettings.Instance.Name;
List<IPublishable> posts= BlogEngine.Core.Post.Posts
.ConvertAll(new Converter<Post, IPublishable>(delegate(Post p) { return pas IPublishable; }));
int pageIndex= (id != null && id.HasValue&& id.Value> 0)? id.Value :1;
int pageSize= Math.Min(posts.Count, BlogSettings.Instance.PostsPerPage);
if ((pageIndex- 1)* pageSize + pageSize > posts.Count)
{
return ShowMsg(new List<string>() { "頁碼超出範圍" });
}
posts = posts.GetRange((pageIndex- 1)* pageSize, pageSize);
ViewData["Posts"]= posts; //向ViewData中傳資料
//這裡返回View給用戶端,如果不指定要返回的View的名稱,
//就是返回和Action同名的View,
//也就是相當於return View("Index");
return View();
}
預設的WebFormView搜尋View的順序是按如下順序搜尋的:
其中{1}為ControllerName,{0}為ActionName。MasterLocationFormats為主版頁面的搜尋順序。
在上面的代碼中我們使用ViewData["Posts"]向View頁面傳遞資料,然後我們就可以在View中取出資料並呈現給使用者,Views/Home/Index.aspx頁面的部分代碼如下:
如上紅色框中的代碼,我們可以從ViewData中取出資料,並轉換為相應的類型。在這裡我們發現ViewData要做一個類型的轉換,其實我們可以將ViewData.Model設定為強型別,只需將我們的View頁面繼承自ViewPage<TModel>就可以了:
然後在Controller裡面return View()的時候直接給ViewData.Model傳值,如下所示:
然後在View中我們可以直接從強型別的ViewData.Model中取值:
由上面的代碼我看可以看出ViewData.Model就是List<IPublishable>類型,並不需要再進行類型的轉換。
ViewData還有一個Eval的方法,我們可以使用這個方法從ViewData中取值。假如我麼在Action中使用return View(Post);給View傳遞一篇日誌的資料。而Post有一個Previous的屬性指向前一篇日誌,則我們可以在View頁面中可以這樣來取值:
<%= ViewData.Eval("Previous.Title")%>
但是如果使用我最後提供的樣本Blog程式的代碼這樣在取值的時候直接在裡面使用"."來取值,你會發現取不了值。因為BlogEngine裡面的BusinessBase類實現了IDataErrorInfo介面,而IDataErrorInfo有一個索引器,也就是說BusinessBase有一個索引器,就因為有一個索引器,使Eval中不能用點來取值(不知道是不是bug?)。
補充:上面說到的不是Bug,是因為BusinessBase實現了IDataErrorInfo介面,該介面有個索引器,導致ViewData.Eval()方法調用時搜尋索引器的值時返回String.Empty而使ViewData.Eval()認為是找到值了,從而失效。
我們可以將return string.Empty修改為return null,這樣就可以了。