现在的位置: 首页 > 综合 > 正文

ASP.NET MVC 入门5、View与ViewData

2013年10月25日 ⁄ 综合 ⁄ 共 2420字 ⁄ 字号 评论关闭

view在MVC模式中与用户进行最直接的接触,它负责数据的呈现。这里要注意一点就是,view只是负责数据的呈现,所以我们应该要尽量让
view中不涉及业务逻辑的处理。

我们来添加一个Blog首页的view。在安装了ASP.NET MVC后,我们在添加新项目的时候可以看到有MVC的view模板:

image
 
注:如果你的是中文版
的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:

image

我们看到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
p
as
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的顺序是按如下顺序搜索的:

image

其中{1}为ControllerName,{0}为ActionName。MasterLocationFormats为母版页的搜索顺序。

在上面的代码中我们使用ViewData["Posts"]向View页面传递数据,然后我们就可以在View中取出数据并呈现给用
户,Views/Home/Index.aspx页面的部分代码如下:

image

如上红色框中的代码,我们可以从ViewData中取出数据,并转换为相应的类型。在这里我们发现ViewData要做一个类型的转换,其实我们可
以将ViewData.Model设置为强类型,只需将我们的View页面继承自ViewPage<TModel>就可以了:

image

然后在Controller里面return View()的时候直接给ViewData.Model传值,如下所示:

image

然后在View中我们可以直接从强类型的ViewData.Model中取值:

image

由上面的代码我看可以看出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()认为是找到值了,从而失效。

image

我们可以将return string.Empty修改为return null,这样就可以了。

抱歉!评论已关闭.