[翻译] ASP.NET MVC Tip #5 – 创建共享视图

原文地址:http://weblogs.asp.net/stephenwalther/archive/2008/06/19/asp-net-mvc-tip-5-create-shared-views.aspx

摘要:在这个Tip中,Stephen Walther介绍了如何为控制器action创建共享视图。共享视图可以用于多个控制器。本文Stephen Walther介绍的是如何为显示和编辑数据库数据来创建共享视图。

假设HomeController控制器暴露了一个名为Index()的action。当调用Index() action时,ASP.NET MVC框架会尝试获取从下面的路径处获取Index视图:

\Views\Home\Index.aspx

如果Home文件夹中没有Index.aspx视图,ASP.NET MVC框架会再次尝试从Shared文件夹获取视图:

\Views\Shared\Index.aspx

如果两个地方都找不到Index.aspx视图,就会显示图1所示的错误消息。

图1 - 尝试访问一个不存在的视图时显示的错误信息


因此,当无法从Views子目录中获取视图时,ASP.NET MVC框架总是会从Shared文件夹中获取视图。这意味着你可以为action方法建立默认视图,并能在多个控制器之间共享。

在今天的Tip中,我会介绍如何为标准的数据库操作创建共享的视图,使其可以与昨天在Tip #4中创建的DataController一起协作。如果你还没有阅读昨天的Tip,请点此阅读:http://www.cnblogs.com/AndersLiu/archive/2008/07/08/asp-net-mvc-tip-4-create-a-custom-data-controller-base-class.html

我为今天这个Tip修改了DataController类,使得控制器action可以向视图返回一个LINQ to SQL DataContext。例如,修改后的DataController.Index()方法如下:

1Public Function Index() As ActionResult
2    ViewData("DataContext"= Me.DataContext
3    ViewData("DataTable"= Me.Table
4    Return View()
5End Function

在呈现数据表格时,我们需要同时知道DataContext和Table。

位于Views\Shared文件夹中的Index.aspx视图,包含清单1所示的代码。

清单1 - Views\Shared\Index.aspx

<%@ Page Title="Index" Language="VB" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.vb" Inherits="Tip5.SharedViews.Index" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
 
<%=Me.RenderDataTable()%>
<br />
<%= Html.ActionLink("Add Record""Create"%>
 
</asp:Content>

清单1中的Index.aspx视图简单调用了一个在后台代码中声明的RenderDataTable()方法。在Index.aspx.vb中——Index.aspx的后台代码里——包含了如清单2所示的代码。

清单2 - Views\Shared\Index.aspx.vb

 1Namespace SharedViews
 2 
 3    Partial Public Class Index
 4        Inherits DataViewBase
 5 
 6 
 7        Protected Function RenderDataTable() As String
 8            Dim sb As New StringBuilder()
 9            sb.AppendLine("<table>")
10 
11            ' Create Header Row
12            Dim columnNames As String() = Me.GetColumnNames()
13            sb.AppendLine("<tr>")
14            sb.Append("<th></th>")
15            For Each columnName As String In columnNames
16                sb.AppendFormat("<th>{0}</th>", columnName)
17            Next
18            sb.AppendLine("</tr>")
19 
20            ' Create Data Rows
21            Dim row As Object
22            For Each row In Me.DataTable
23                Dim identityValue As Integer = Me.GetIdentityValue(row)
24                sb.AppendLine("<tr>")
25                sb.Append("<td><small>")
26                sb.Append(Me.Html.ActionLink("[View]""Details"New With {.Id = identityValue}))
27                sb.Append("&nbsp;")
28                sb.Append(Me.Html.ActionLink("[Edit]""Edit"New With {.Id = identityValue}))
29                sb.Append("&nbsp;")
30                sb.Append(Me.Html.ActionLink("[Delete]""Delete"New With {.Id = identityValue}))
31                sb.Append("</small></td>")
32                For Each columnName As String In columnNames
33                    Dim value As String = row.GetType() _
34                        .GetProperty(columnName) _
35                        .GetValue(row, Nothing) _
36                        .ToString()
37                    sb.AppendFormat("<td>{0}</td>", HttpUtility.HtmlEncode(value))
38                Next
39                sb.AppendLine("</tr>")
40            Next
41 
42            sb.AppendLine("</table>")
43            Return sb.ToString()
44        End Function

45 
46    End Class

47End Namespace

48

RenderDataTable()方法生成了一个HTML表格,其中包含了DataTable属性中的所有列和所有行。DataTable是DataController.Index()控制器传递给Index.aspx视图的。

当请求Index.aspx视图时,你可以得到如图2所示的页面。

图2 - Index.aspx视图


注意在每条记录前面都有View、Edit和Delete链接。单击这些链接可以执行对应的操作。注意除此之外,页面底部还有一个Add Record链接。单击这个连接可以打开Create.aspx视图,如图3。

图3 - Create.aspx视图


Create.aspx视图生成的表单并不漂亮,也不支持验证,但它能够工作。如果你输入一个新的电影信息,你可以将其提交到数据库。

Create表单是由清单3所示的代码生成的。

清单3 - Views\Shared\Create.aspx.vb

 1Namespace SharedViews
 2 
 3    Partial Public Class Create
 4        Inherits DataViewBase
 5 
 6 
 7 
 8        Protected Function RenderCreateForm() As String
 9            Dim sb As New StringBuilder()
10            Dim columnNames = Me.GetColumnNames()
11            Dim identityColumnName = Me.GetIdentityColumnName()
12 
13            sb.AppendFormat("<form method='post' action='{0}'>"Me.Url.Action("New"))
14            sb.AppendLine("<table>")
15            Dim columnName As String
16            For Each columnName In columnNames
17                If columnName <> identityColumnName Then
18                    sb.AppendLine("<tr>")
19                    sb.AppendFormat("<th><label for='{0}'>{0}:</label></td>", columnName)
20                    sb.AppendFormat("<td><input name='{0}' type='text' /></td>", columnName)
21                    sb.AppendLine("</tr>")
22                End If
23            Next
24            sb.AppendLine("</table>")
25            sb.AppendLine("<input type='submit' value='Add Record' />")
26            sb.AppendLine("</form>")
27 
28            Return sb.ToString()
29        End Function

30 
31    End Class

32End Namespace

清单3中的代码使用DataContext和Table自动生成了表单。上述两个对象都是由DataController.Create()方法传递过来的。

该Tip的目的是给你一些灵感,告诉你可以用共享视图做些什么。在这个Tip中,我们看到了如何使用共享视图来为数据库中的数据自动生成显示、编辑和插入表单。你可以按照类似的方法为其他类型的控制器action创建共享视图(例如,标准的购物车视图)。

此处下载源代码:http://weblogs.asp.net/blogs/stephenwalther/Downloads/Tip5/Tip5.zip

-----

广告:欢迎光临[.NET正则表达式](http://regex-lib.net/)。

posted @ 2008-07-10 22:03  Anders Liu  阅读(2496)  评论(5编辑  收藏  举报