CSLA.NET快速入门系列——快速构建应用(下)
上篇我们介绍了通过CodeSmith模板生成了业务对象库,本篇我们接着介绍怎么使用业务对象库来实现业务应用。
UI层我们通过asp.net来实现,参照一般的应用功能的划分方式,实现以下业务功能:
1. 任务列表
2. 新增任务(同时可新增任务资源)
3.修改任务(同时可管理任务资源)
我们在UI项目中通过两个界面来实现以上3个功能:
1. TaskListForm.aspx (实现功能1,任务列表。在此界面中可以删除任务,也可以导航到新增和修改任务功能)
2. AddTaskForm.aspx (实现功能2,3。)
为了能够使用CSLA的数据绑定控件,我们需要UI项目中添加对Csla.Web.dll引用,同时在VS2010的工具栏中添加Csla.Web的工具选项。
修改Web.Config,在System.Web节中增加以下代码:
View Code <controls>
<add tagPrefix="csla" namespace="Csla.Web" assembly="Csla.Web"/>
</controls>
</pages>
在UI项目增加两个ASPX页面:TaskListForm.aspx和AddTaskForm.aspx
实现 TaskListForm.aspx的步骤:
1. 从工具栏拖入一个GridView控件到页面中,用来显示任务列表信息,将Id更改为:gvTask
2. 从工具栏拖入一个CslaDataSource控件到页面中,用来加载任务列表的数据源,将Id更改为:taskDataSource
3. 从工具栏拖入一个LinkButton控件到页面中,用作为新增任务链接,将Id更改为:lbCreate,将Text设置为:创建任务
4. 从工具栏拖入一个Lable控件到页面中,用作为显示提示信息,将Id更改为:lblMsg,将Text设置为空
5. 将 taskDataSource 控件的TypeName属性设置为我们要绑定的业务对象列表类型(全名,含程序集名):Demo.Business.TaskList,Demo.Business。
taskDataSource的代码如下:
View Code TypeName="Demo.Business.TaskList,Demo.Business" TypeSupportsPaging="False"
TypeSupportsSorting="False" ></csla:CslaDataSource>
6. 为 gvTask 选择数据源为taskDataSource,同时启用分页,启用删除,启用选择内容。修改绑定列的标题;变更日期格式为:{0:yyyy-MM-dd}。为了显示效果,可以选择传统型的风格。gvTask的代码如下:
View Code AutoGenerateColumns="False"
DataSourceID="taskDataSource" CellPadding="4" ForeColor="#333333"
GridLines="None" onrowdeleted="gvTask_RowDeleted"
DataKeyNames="Identification"
onselectedindexchanged="gvTask_SelectedIndexChanged">
<FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#EFF3FB" />
<PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
<Columns>
<asp:BoundField DataField="Identification" HeaderText="任务Id"
InsertVisible="False" ReadOnly="True" SortExpression="Identification" />
<asp:BoundField DataField="TaskName" HeaderText="任务名称"
SortExpression="TaskName" />
<asp:BoundField DataField="PrincipalUser" HeaderText="用户"
SortExpression="PrincipalUser" />
<asp:BoundField DataField="StartSchedule" HeaderText="开始时间"
SortExpression="StartSchedule" DataFormatString="{0:yyyy-MM-dd}" />
<asp:BoundField DataField="ActualFinishTime" HeaderText="实际完成时间"
SortExpression="ActualFinishTime" DataFormatString="{0:yyyy-MM-dd}" />
<asp:CommandField ShowSelectButton="True" />
<asp:CommandField ShowDeleteButton="True" />
</Columns>
<EditRowStyle BackColor="#2461BF" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
现在来看看我们的成果,如下图所示:
接下来的步骤主要跟后台代码相关 :
7. 为taskDataSource注册事件处理方法
DeleteObject事件处理方法taskDataSource_DeleteObject,用来处理在数据源中删除一条任务信息
SelectObject事件处理方法taskDataSource_SelectObject,用来指定业务对象(任务列表)
后台代码如下:
View Code 2 protected void taskDataSource_DeleteObject(object sender, Csla.Web.DeleteObjectArgs e)
3 {
4 decimal key = decimal.Parse(e.Keys["Identification"].ToString());
5 try
6 {
7 Task.DeleteTask(key);
8 e.RowsAffected = 1;
9 }
10 catch (Csla.DataPortalException ex)
11 {
12 showMessage(ex.BusinessException.Message);
13 e.RowsAffected = 0;
14 }
15 catch (Exception ex)
16 {
17 showMessage( ex.Message);
18 e.RowsAffected = 0;
19 }
20 }
21
22 protected void taskDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
23 {
24 e.BusinessObject = getTaskList();
25 }
26 #endregion
8. 为gvTask注册事件处理方法
RowDeleted事件处理方法gvTask_RowDeleted,用来处理当数据源中任务删除后刷新控件绑定
SelectedIndexChanged事件处理方法gvTask_SelectedIndexChanged,用来导航到修改任务功能
后台代码如下:
View Code 2 protected void gvTask_RowDeleted(object sender, GridViewDeletedEventArgs e)
3 {
4 Session["currentObject"] = null;
5 gvTask.DataBind();
6 }
7
8 protected void gvTask_SelectedIndexChanged(object sender, EventArgs e)
9 {
10 Response.Redirect("AddTaskForm.aspx?id=" + gvTask.SelectedDataKey.Value);
11 }
12
13
14 #endregion
9. 为lbCreate注册事件处理方法
Click事件处理方法lbCreate_Click,用来导航到新增任务功能
后台代码如下:
View Code 2 {
3 Response.Redirect("AddTaskForm.aspx");
4 }
10. 在后台实现以下私有方法:
void showMsg(string msg) 显示提示信息
TaskList getTaskList() 获取任务列表
void ApplyAuthorizationRules() 应用授权
后台代码如下:
View Code 2 /// <summary>
3 /// 显示消息
4 /// </summary>
5 /// <param name="msg"></param>
6 private void showMessage(string msg)
7 {
8 lblMsg.Text = msg;
9 }
10
11 /// <summary>
12 /// 获取业务对象集合方法
13 /// </summary>
14 /// <returns></returns>
15 private TaskList getTaskList()
16 {
17 object businessObject = Session["currentObject"];
18 if (businessObject == null ||
19 !(businessObject is TaskList))
20 {
21 businessObject =
22 TaskList.GetAll();
23 Session["currentObject"] = businessObject;
24 }
25 return (TaskList)businessObject;
26 }
27
28 /// <summary>
29 /// 应用授权规则方法
30 /// </summary>
31 private void ApplyAuthorizationRules()
32 {
33 if (!Csla.ApplicationContext.User.Identity.IsAuthenticated)
34 {
35 Response.Redirect("login.aspx");
36 }
37
38 Type objectType = typeof(Task);
39
40 this.gvTask.Columns[6].Visible = BusinessRules.HasPermission(AuthorizationActions.DeleteObject, objectType);
41 lbCreate.Visible = BusinessRules.HasPermission(AuthorizationActions.CreateObject, objectType);
42 }
43 #endregion
11. 在页面装载事件处理处理程序中调用授权控制:
View Code 2 {
3 if (!IsPostBack)
4 {
5 Session["currentObject"] = null;
6 ApplyAuthorizationRules();
7 }
8 else
9 {
10 showMessage("");
11 }
12 }
现在我们已经完成了功能1,任务列表页面
实现 AddTaskForm.aspx的步骤:
(本页面实现功能2和功能3,通过是否传递Id参数来确定是新增任务还是修改任务 )
1. 从工具栏拖入一个DetailsView控件到页面中,用来操作任务信息,将Id更改为:dvTask
2. 从工具栏拖入一个Button控件到页面中,用来进行新增任务资源操作,将Id更改为:btnNew ,将Text设置为:新增资源
3. 从工具栏拖入一个GridView控件到页面中,用来操作任务资源列表信息,将Id更改为:gvResources
4. 从工具栏拖入一个Lable控件到页面中,用来显示提示消息,将Id更改为:lblMsg
5. 从工具栏拖入两个CslaDataSource控件到页面中,用来加载任务和任务资源列表数据源,将Id分别更改为:TaskDataSource ,TaskResourceListDataSource
TaskDataSource配置数据源为:Demo.Business.Task, Demo.Business
TaskResourceListDataSource 配置数据源为:Demo.Business.TaskResourceList, Demo.Business
代码如下:
View Code TypeAssemblyName=""
TypeName="Demo.Business.Task, Demo.Business" TypeSupportsPaging="False"
TypeSupportsSorting="False">
</csla:CslaDataSource>
<csla:CslaDataSource ID="TaskResourceListDataSource" runat="server"
TypeAssemblyName="" TypeName="Demo.Business.TaskResourceList, Demo.Business" TypeSupportsPaging="False"
TypeSupportsSorting="False">
</csla:CslaDataSource>
6. 从工具栏拖入一个Button控件到页面中,用来进行新增任务资源操作,将Id更改为:btnReturn ,将Text设置为:返回列表
7. 为 dvTask 选择数据源为TaskDataSource,同时启用插入,启用编辑。修改绑定列的标题;变更日期格式为:{0:yyyy-MM-dd}。为了显示效果,可以选择传统型的风格。
为 gvResources选择数据源为TaskResourceListDataSource,同时启用编辑,启用删除。修改绑定列的标题;变更TaskId为只读。为了显示效果,可以选择传统型的风格。
代码如下:
View Code CellPadding="4" ForeColor="#333333" GridLines="None"
DataKeyNames="Identification">
<Fields>
<asp:BoundField DataField="Identification" HeaderText="任务ID"
InsertVisible="False" ReadOnly="True" SortExpression="Identification" />
<asp:BoundField DataField="TaskName" HeaderText="任务名称"
SortExpression="TaskName" />
<asp:BoundField DataField="PrincipalUser" HeaderText="用户"
SortExpression="PrincipalUser" />
<asp:BoundField DataField="StartSchedule" HeaderText="开始时间"
SortExpression="StartSchedule" ApplyFormatInEditMode="True"
DataFormatString="{0:yyyy-MM-dd}" />
<asp:BoundField DataField="ActualFinishTime" HeaderText="实际完成时间"
SortExpression="ActualFinishTime" ApplyFormatInEditMode="True"
DataFormatString="{0:yyyy-MM-dd}" />
<asp:CommandField ShowEditButton="True"
ShowInsertButton="True" />
</Fields>
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<CommandRowStyle BackColor="#E2DED6" Font-Bold="True" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<FieldHeaderStyle BackColor="#E9ECF1" Font-Bold="True" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
</asp:DetailsView>
<asp:GridView ID="gvResources" runat="server" AutoGenerateColumns="False"
DataSourceID="TaskResourceListDataSource" DataKeyNames="Identification">
<Columns>
<asp:BoundField DataField="Identification" HeaderText="资源ID"
ReadOnly="True" SortExpression="Identification" />
<asp:BoundField DataField="TaskId" HeaderText="任务Id"
SortExpression="TaskId" ReadOnly="True" />
<asp:BoundField DataField="ResourceName" HeaderText="资源名称"
SortExpression="ResourceName" />
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
</Columns>
</asp:GridView>
至此,界面设计完成,如下图:

接下来实现后台代码 :
9. 为TaskDataSource注册事件处理方法
InsertObject事件处理方法TaskDataSource_InsertObject,用来处理在数据源中增加一条任务信息
SelectObject事件处理方法TaskDataSource_SelectObject,用来指定业务对象(任务信息)
TaskDataSource事件处理方法TaskDataSource_UpdateObject,用来处理在数据源中更新一条任务信息
后台代码如下:
View Code 2 /// <summary>
3 /// 新增任务处理事件
4 /// </summary>
5 /// <param name="sender"></param>
6 /// <param name="e"></param>
7 protected void TaskDataSource_InsertObject(object sender, Csla.Web.InsertObjectArgs e)
8 {
9 Task obj = getTask();
10 try
11 {
12 Csla.Data.DataMapper.Map(e.Values, obj, "Identification");
13 }
14 catch (Exception ex)
15 {
16 showMessage(ex.Message);
17
18 return;
19 }
20 e.RowsAffected = saveTask(obj);
21 }
22
23 /// <summary>
24 /// 初始事件
25 /// </summary>
26 /// <param name="sender"></param>
27 /// <param name="e"></param>
28 protected void TaskDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
29 {
30 e.BusinessObject = getTask();
31 }
32
33 /// <summary>
34 /// 更新任务处理事件
35 /// </summary>
36 /// <param name="sender"></param>
37 /// <param name="e"></param>
38 protected void TaskDataSource_UpdateObject(object sender, Csla.Web.UpdateObjectArgs e)
39 {
40 Task obj = getTask();
41 Csla.Data.DataMapper.Map(e.Values, obj);
42 e.RowsAffected = saveTask(obj);
43 }
44 #endregion
10.为TaskResourceListDataSource注册事件处理方法
DeleteObject事件处理方法TaskResourceDataSource_DeleteObject,用来处理在数据源中删除一条任务资源信息
SelectObject事件处理方法TaskResourceListDataSource_SelectObject,用来指定业务对象(任务资源信息)
TaskDataSource事件处理方法TaskResourceListDataSource_UpdateObject,用来处理在数据源中更新一条任务资源信息
后台代码如下:
View Code 2 protected void TaskResourceDataSource_DeleteObject(object sender, Csla.Web.DeleteObjectArgs e)
3 {
4 Task task = getTask();
5 decimal id = decimal.Parse(e.Keys["Identification"].ToString());
6 TaskResource trr = task.TaskResources.First(p => p.Identification == id);
7 if (trr != null)
8 {
9 task.TaskResources.Remove(trr);
10 e.RowsAffected = saveTask(task);
11 }
12
13 }
14
15 protected void TaskResourceDataSource_SelectObject(object sender, Csla.Web.SelectObjectArgs e)
16 {
17 Task task = getTask();
18 e.BusinessObject = task.TaskResources;
19 }
20
21 protected void TaskResourceDataSource_UpdateObject(object sender, Csla.Web.UpdateObjectArgs e)
22 {
23 Task task = getTask();
24 decimal id = decimal.Parse(e.Keys["Identification"].ToString());
25 TaskResource trr = task.TaskResources.First(p => p.Identification == id);
26 if (trr != null)
27 {
28 DataMapper.Map(e.Values, trr);
29 e.RowsAffected = saveTask(task);
30 }
31
32 }
33 #endregion
11. 为dvTask注册事件处理方法
ItemInserted事件处理方法dvTask_ItemInserted,用来处理当数据源中任务插入完成后的处理
ItemUpdated事件处理方法dvTask_ItemUpdated,用来处理当数据源中任务更新完成后的处理
后台代码如下:
View Code 2
3 /// <summary>
4 /// 新增条目后事件
5 /// </summary>
6 /// <param name="sender"></param>
7 /// <param name="e"></param>
8 protected void dvTask_ItemInserted(object sender, DetailsViewInsertedEventArgs e)
9 {
10 Task obj = getTask();
11 if (!obj.IsNew)
12 {
13 Response.Redirect("AddTaskForm.aspx?id=" + obj.Identification);
14 }
15
16 }
17
18 /// <summary>
19 /// 更新记录后事件
20 /// </summary>
21 /// <param name="sender"></param>
22 /// <param name="e"></param>
23 protected void dvTask_ItemUpdated(object sender, DetailsViewUpdatedEventArgs e)
24 {
25 ApplyAuthorizationRules();
26 }
27 #endregion
12. 为btnNew注册事件处理方法
Click事件处理方法btnNew_Click,用来处理新增任务资源
后台代码如下:
View Code 2 {
3 createResource();
4 }
13. 为btnReturn注册事件处理方法
Click事件处理方法btnReturn_Click,用来导航到任务列表功能页面
后台代码如下:
View Code 2 {
3 Response.Redirect("TaskListForm.aspx");
4 }
14. 在后台实现以下私有方法:
void showMsg(string msg) 显示提示信息
Task getTask() 获取任务信息
void createResource() 新增任务资源
int saveTask(Task task) 保存任务信息到数据源
void ApplyAuthorizationRules() 应用授权
后台代码如下:
View Code 2 /// <summary>
3 /// 显示消息
4 /// </summary>
5 /// <param name="msg"></param>
6 private void showMessage(string msg)
7 {
8 lblMsg.Text = msg;
9 }
10
11 /// <summary>
12 /// 应用授权规则
13 /// </summary>
14 private void ApplyAuthorizationRules()
15 {
16 Task obj = getTask();
17 // 是否有权限编辑任务
18 bool canEditTask = BusinessRules.HasPermission(AuthorizationActions.CreateObject, obj.GetType());
19
20 if (canEditTask)
21 {
22 if (obj.IsNew)
23 this.dvTask.DefaultMode = DetailsViewMode.Insert;
24 else
25 this.dvTask.DefaultMode = DetailsViewMode.Edit;
26 }
27 else
28 {
29 this.dvTask.DefaultMode = DetailsViewMode.ReadOnly;
30 }
31 this.dvTask.Rows[
32 this.dvTask.Rows.Count - 1].Visible = canEditTask;
33 }
34 /// <summary>
35 /// 获取业务对象方法
36 /// </summary>
37 /// <returns></returns>
38 private Task getTask()
39 {
40 object businessObject = Session["currentObject"];
41 if (businessObject == null ||
42 !(businessObject is Task))
43 {
44 try
45 {
46 string idString = Request.QueryString["id"];
47 if (!string.IsNullOrEmpty(idString))
48 {
49 decimal id = decimal.Parse(idString);
50 businessObject = Task.GetByIdentification(id);
51 }
52 else
53 {
54 businessObject = Task.NewTask();
55 }
56
57 Session["currentObject"] = businessObject;
58 }
59 catch (System.Security.SecurityException se)
60 {
61 Response.Redirect("TaskListForm.aspx");
62 }
63
64 }
65 return (Task)businessObject;
66 }
67
68 /// <summary>
69 /// 保存业务对象到持久层
70 /// </summary>
71 /// <param name="task"></param>
72 /// <returns></returns>
73 private int saveTask(Task task)
74 {
75 int rowsAffected;
76 try
77 {
78 Session["currentObject"] = task.Save();
79 rowsAffected = 1;
80 }
81 catch (ValidationException ex)
82 {
83 System.Text.StringBuilder message = new System.Text.StringBuilder();
84 message.AppendFormat("{0}", ex.Message);
85 if (task.BrokenRulesCollection.Count > 0)
86 {
87 message.Append("<ul>");
88 foreach (BrokenRule rule in task.BrokenRulesCollection)
89 message.AppendFormat("<li>{0}: {1}</li>", rule.Property, rule.Description);
90 message.Append("</ul>");
91 }
92 showMessage(message.ToString());
93 rowsAffected = 0;
94 }
95 catch (Csla.DataPortalException ex)
96 {
97 showMessage(ex.BusinessException.Message);
98 rowsAffected = 0;
99 }
100 catch (Exception ex)
101 {
102 showMessage(ex.Message);
103 rowsAffected = 0;
104 throw ex;
105 }
106 return rowsAffected;
107 }
108
109 /// <summary>
110 /// 新增任务资源
111 /// </summary>
112 private void createResource()
113 {
114 Task task = getTask();
115 TaskResource trr = task.TaskResources.AddNew();
116 this.gvResources.DataBind();
117 }
118
119 #endregion
15. 在页面装载事件处理处理程序中调用授权控制:
View Code 2 {
3 if (!IsPostBack)
4 {
5 Session["currentObject"] = null;
6 ApplyAuthorizationRules();
7 }
8 else
9 {
10
11
12 showMessage("");
13 }
14 }
至止,我们完成了功能2和功能3的页面:AddTaskForm.aspx
最后,我们在Default.aspx页面加上任务列表和新增任务的导航,代码如下:
View Code <a href="TaskListForm.aspx">任务列表</a> | <a href="AddTaskForm.aspx">创建新任务</a>
</div>
现在,我们已经完成整个demo的应用构建,开发过程非常简单快捷,demo源代码可在此处下载。在前面的介绍中,并没有对CSLA本身的特性进行介绍,只是简单介绍如何利用CSLA框架快速生成并实现应用,从下一篇开始,将会从CSLA的不同特性分别进行介绍,希望能够对大家应用CSLA开发有所帮助。

浙公网安备 33010602011771号