用视图呈现UI
视图可以不包含任何应用逻辑或者数据库检索代码,所有的应用逻辑都可以在controller中进行处理。
视图通过使用controller类在调用RenderView方法的时候提供视图相关数据对象呈现UI:
public
void
Categories()
{
List
<
Category
>
categories
=
northwind.GetCategories();
RenderView(
"
Categories
"
, categories);
}
禁止访问Views目录
为了在你的ASP.NET MVC WEB应用程序中添加额外的安全性,你可以直接阻止访问Views目录。添加如下的代码到你Views目录下的web.config中的system.web节下就可以了:
<
authorization
>
<
deny
users
="*"
/>
< /
authorization
>
ASPX视图页
ViewPage类型的视图页是Page类的一个实例。我们看一下下面的视图页:
using
System;
using
System.Configuration;
using
System.Collections;
using
System.Web;
using
System.Web.Mvc;
namespace
MvcApplication.Views.Home
{
public partial class Index : ViewPage< CompanyInfo>
{
}
}
它继承自ViewPage< T>,我们看一下继承关系:
using
System;
namespace
System.Web.Mvc
{
public
class
ViewPage
<
TViewData
>
: ViewPage
{
public
ViewPage();
public
TViewData ViewData {
get
; }
protected
internal
override
void
SetViewData(
object
viewData);
}
}
而ViewPage< T>又继承自ViewPage:
这里注意一下ViewPage提供的公共方法,经常要用到的。
而ViewPage还实现了一个IViewDataContainer的接口,这个接口里面只有一个属性,就是我们经常用的ViewData :
下面的示例演示了如何使用ViewData属性,这个属性有两中变异。如果你的View继承自System.Web.Mvc.ViewPage类,则ViewData属性是一个dictionary.这个属性提供一个索引器接收一个dictionay键.下面是继承自System.Web.Mvc.ViewPage类的示例:
< %
@ Page Language="C#" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="MvcApplication5.Views.Home.About"
%>
<
html
xmlns
="http://www.w3.org/1999/xhtml"
>
<
head
id
="Head1"
runat
="server"
>
<
title
>
ViewData Property - Dictionary Based
< /
title
>
< /
head
>
<
body
>
<
div
>
< %
=
"
About
"
+
ViewData[
"
CompanyName
"
]
%>
< /
div
>
< /
body
>
< /
html
>
当然,我们还可以使用一个强类型的ViewData属性.这个为数据从控制器传递到视图中提供更好的类型检测.下面的示例是使用强类型的ViewData,视图页是继承自ViewPage< T>的:
< %
@ Page Language="C#" AutoEventWireup="true" CodeBehind="About.aspx.cs" Inherits="MvcApplication.Views.Billing.Account"
%>
<
head
id
="Head1"
runat
="server"
>
<
title
>
ViewData Property - Strongly Typed
< /
title
>
< /
head
>
<
body
>
<
div
>
< %
=
"
About
"
+
ViewData.CompanyName
%>
< /
div
>
< /
body
>
设置视图数据
通常,你提供数据给视图来呈现.要呈现视图,你调用控制器中的RenderView方法.这里有两种途径来将数据从控制器传递到视图中.Controller类暴露一个ViewData的属性,它返回键大小写无关的IDictionay< string,object>类型.你可以分配索引值到这个数据字典中.看下面的示例:
public
SampleController : Controller
{
public
void
Welcome()
{
ViewData[
"
FirstName
"
]
=
"
Joe
"
;
ViewData[
"
LastName
"
]
=
"
Healy
"
;
RenderView(
"
Welcome
"
);
}
}
如果只是用一个视图名来调用RenderView方法,就像上面的示例所示,这个Controller对象的ViewData属性会被作为dictionary来传递给View.如果你希望使用一个强类型的ViewData属性,你可以忽略ViewData属性.作为代替,你创建一个你想传递到View中的对象,然后将它传递给RenderView方法.就如下面示例所示:
public
class
SampleViewData
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public
SampleController : Controller
{
public void Welcome() {
SampleViewData viewData = new SampleViewData();
viewData.FirstName = "Joe";
viewData.LastName = "Healy";
RenderView("Welcome", viewData);
}
}
在Actions方法之间传递状态
Action方法很可能必需传递数据到另外一个Action中,就好像当一个form提交的时候发生了错误,那样的话,用户应该被重定向到一个可以显示出错信息的页面中.
在Action方法调用控制器的RedirectToAction方法调用其他Action之前,Action方法可以设置Controller的TempData属性到任意一个对象.这个TempData属性值是保存在session中的.另外一个Action可以检查TempData属性并获取值来在它自己的视图中显示.TempData的值只是在一个请求到下一个请求中保留.
下面是示例演示了如何捕捉错误并重定向到一个使用原始数据的错误页中:
<
form
action
="/App/InsertCustomer"
>
< %
if (ViewData.ErrorMessage != null) {
%>
The following error occurred while inserting the customer data:
<
br
/>
< %
=
ViewData.ErrorMessage
%>
<
br
/>
< %
}
%>
First name:
<
input
type
="text"
name
="firstName"
value
="< %= ViewData.FirstName %>"
/><
br
/>
Last name:
<
input
type
="text"
name
="lastName"
value
="< %= ViewData.LastName %>"
/><
br
/>
<
input
type
="submit"
value
="Insert"
/>
< /
form
>
Action间传递数据
public class InsertError {
public string ErrorMessage { get; set; }
public string OriginalFirstName { get; set; }
public string OriginalLastName { get; set; }
}
// CustomersController
public void InsertCustomer(string firstName, string lastName) {
// Check for input errors.
if (String.IsNullOrEmpty(firstName) ||
String.IsNullOrEmpty(lastName)) {
TempData["error"] = new InsertError("Both names required",
firstName, lastName);
RedirectToAction("NewCustomer");
return;
}
// No errors
//
}
public void NewCustomer() {
InsertError err = TempData as InsertError;
if (err != null) {
// If there is error data from the previous action, display it.
ViewData.FirstName = err.OriginalFirstName;
ViewData.LastName = err.OriginalLastName;
ViewData.ErrorMessage = err. ErrorMessage;
}
//
}