怎样创建一个.NET RIA Services Application (二)

简介:  这段时间比较忙,但还是抽时间把这篇给补完了。下篇主要讲.net RIA Services Domain Class 的数据验证功能和DataForm的插入更新操作,以及用户对操作的访问权限控制。等以后有时间再深入探讨RIA Services的Generator Code运行机制。
 这段时间比较忙,但还是抽时间把这篇给补完了。下篇主要讲.net RIA Services Domain Class 的数据验证功能和DataForm的插入更新操作,以及用户对操作的访问权限控制。等以后有时间再深入探讨RIA Services的Generator Code运行机制。

1 Employee详细设计

1.1 添加一个DataForm

我们将使用来自SL 3 Toolkit中的 DataForm 控件. 这个是由 Silverlight Business Application Project 模板中自动加入的System.Windows.Controls.Data.DataForm.Toolkit.dll动态库提供, 我们添加这个控件到页面上。

1. 选择EmployeeList.xaml.

2. 向EmployeeList.xaml 添加命名空间引用

xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" 

3. 添加下面的代码到Xaml.

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
<dataForm:DataForm x:Name="dataForm1" Header="Employee Information" AutoGenerateFields="False" AutoEdit="False" AutoCommit="False" CurrentItem="{Binding SelectedItem, ElementName=dataGrid1}" Margin="0,12,0,0"> 

<dataForm:DataForm.EditTemplate> 

<DataTemplate> 

<StackPanel> 

<dataForm:DataField Label="Employee ID"> 

<TextBox Text="{Binding EmployeeID, Mode=TwoWay}" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Login ID"> 

<TextBox Text="{Binding LoginID, Mode=TwoWay}" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Hire Date"> 

<TextBox Text="{Binding HireDate, Mode=TwoWay}" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Marital Status"> 

<TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Gender"> 

<TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Vacation Hours"> 

<TextBox Text="{Binding VacationHours, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Sick Leave Hours"> 

<TextBox Text="{Binding SickLeaveHours, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> 

</dataForm:DataField> 

<dataForm:DataField Label="Active"> 

<CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay,NotifyOnValidationError=True, ValidatesOnExceptions=True }" /> 

</dataForm:DataField> 

</StackPanel> 

</DataTemplate> 

</dataForm:DataForm.EditTemplate> 

</dataForm:DataForm>

4. 运行项目点击 employee list 链接. DataForm 显示在DataGrid 中选中的项的详细数据。
其实就是绑定到一个对象上。

clip_image002

2 更新数据库

2.1 更新记录

如果你在新建数据服务模型的时候使用了Enable editing 选项 ,系统会在自动生成服务类中包含各种更新,插入的方法,而在项目中,我们提供按钮使这些方法能被调用。

1. 添加Submit按钮.

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
<!-- XAML --> 

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0"> 

<Button x:Name="submitButton" Width="75" Height="23" Content="Submit" Margin="4,0,0,0" Click="submitButton_Click"/> 

</StackPanel> 

2. 按钮事件

 

//  C# 
private   void  submitButton_Click( object  sender, RoutedEventArgs e) 

     employeeDataSource.SubmitChanges(); 


3. 运行程序,你会发现已经可以更改数据并进行保存了.

2.2 添加客户业务到服务类

1. 在项目中,打开OrganizationService.cs 并建立函数ApproveSabbatical.

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
// C# 

public void ApproveSabbatical(Employee current) 
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif

    
// Start custom workflow here 
    if (current.EntityState == EntityState.Detached) 
img_2887d91d0594ef8793c1db92b8a1d545.gifimg_7a2b9a960ee9a98bfd25d306d55009f8.gif    

        
this.Context.Attach(current); 
    }
 
    current.CurrentFlag = false
}
 

2. 编译后在提交按钮下再添加一个按钮

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0"> 
     
<Button x:Name="submitButton" Width="75" Height="23" Content="Save" Margin="4,0,0,0" Click="submitButton_Click"/> 
     
<Button x:Name="approveSabbatical" Width="115" Height="23" Content="Approve Sabbatical" Margin="4,0,0,0"  Click="approveSabbatical_Click"/> 
</StackPanel> 

3. 打开后台代码,添加按钮事件

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
// C# 
private void approveSabbatical_Click(object sender, RoutedEventArgs e) 
img_405b18b4b6584ae338e0f6ecaf736533.gifimg_1c53668bcee393edac0d7b3b3daff1ae.gif
{
    Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem); 
    luckyEmployee.ApproveSabbatical(); 
    employeeDataSource.SubmitChanges(); 
}

4. 运行并点击ApproveSabbatical 按钮

3 验证

3.1 基本验证

DataForm 控件具有显示来自数据访问层(DAL)错误信息的能力. 例如下图,当输入一个非法值时,会产生比较美观的错误提示.

clip_image004

打开HRApp.web 工程下的OrganizationService.metadata.cs文件,这个是由DomainService类根据实体模型自动生成的 验证扩展类。而为了能让这些验证规则在客户端自动生成,我们需要为这些属性添加验证类型,通常验证类型都是以Attribute的方式添加,共有有下面几种:

  •  CustomValidationAttribute
  •  DataTypeAttribute
  •  RangeAttribute
  •  RegularExpressionAttribute
  •  RequiredAttribute
  •  StringLengthAttribute

1. 打开OrganizationService.metadata.cs文件,添加基本验证.

//  C# 
[Required] 
public   string  Gender; 
[Range( 0 70 )] 
public   short  VacationHours; 

2. 编译项目,并运行(注意要选择直接运行不调试Start Without Debugging)

Note: 因为这种基本数据验证是以异常抛出,调试器会先于程序捕获这种异常,会报错.

3. 运行程序,在VacationHours字段上输入超出范围(0-70)的数据. 你会看到如下图示。当然,Gender字段被设定成Required ,即不能为空。

clip_image006

3.2 自定义验证

1. 在HRApp.web项目中添加一个用户类,命名为OrganizationService.shared.cs.
注意命名规则,这是一个共享类,就是在服务器端和客户端都会使用到,而在客户端会由程序自动生成对应类,这种类必须以shared.cs结尾。

2. 我们在该类中添加下面的代码。

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
// C# 
using System; 
using System.ComponentModel.DataAnnotations; 
using System.Web.Ria.Data;
namespace HRApp.Web
{
    
public static class GenderValidator
    {
        
public static ValidationResult IsGenderValid(string gender, ValidationContext context)
        {
            
if (gender == "M" || gender == "m" || gender == "F" || gender == "f")
            {
                
return ValidationResult.Success;
            }
            
else
            {
                
return new ValidationResult("The Gender field only has two valid values 'M'/'F'"); ;
            }
        }
    }
}

3. 打开 OrganizationService.metadata.cs 现在我们可以在字段上添加CustomValidation,将刚才生成的类类型做为参数,验证条件是返回值为ValidationResult类型的函数。

//  C# 
[CustomValidation( typeof (HRApp.Web.GenderValidator),  " IsGenderValid " )] 
[Required] 
public   string  Gender; 

4. 编译运行,在 employee dataForm 中,输入一个不是 ’M’ 或’F’的非法值.看到验证信息如下。

clip_image008

3.3 添加一条记录

现在我们将创建一个用户接口,用于实现添加新记录到数据库. 当然这其中也包含验证条件

1. 在HRApp项目中添加新项,Silverlight Child Window命名EmployeeRegistrationWindow.xaml.

clip_image010

2. 打开EmployeeRegistrationWindow.xaml.cs 添加命名空间

// C#

using HRApp.Web;

3. 添加属性

// C#

public Employee NewEmployee { get; set; }

4. 打开 EmployeeRegistrationWindow.xaml.

5. 隐藏ChildWindow 窗口的关闭按钮.

< controls:ChildWindow  x:Class ="HRApp.EmployeeRegistrationWindow"  
… 
Width ="400"  Height ="300"  
Title ="EmployeeRegistrationWindow"  HasCloseButton ="False" >  

6. 我们制作对象详细视图,需要使用 System.Windows.Controls.Data.DataForm.Toolkit 中的控件,这在Sivlerlight Business Project 模板中已经为我们引入了,在Libs目录下。我们添加引用集后就可以直接使用DataForm了。

xmlns:dataForm="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm.Toolkit" 

7. 向EmployeeRegistrationWindow.xaml添加 DataForm,放在取消按钮上面。

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
        <dataForm:DataForm x:Name="addEmployeeDataForm"   AutoGenerateFields="False" AutoCommit="True" AutoEdit="True" CommandButtonsVisibility="None">
            
<dataForm:DataForm.EditTemplate>
                
<DataTemplate>
                    
<StackPanel>
                        
<dataForm:DataField Label="Login ID">
                            
<TextBox Text="{Binding LoginID, Mode=TwoWay}" />
                        
</dataForm:DataField>
                        
<dataForm:DataField Label="National ID">
                            
<TextBox Text="{Binding NationalIDNumber, Mode=TwoWay}" />
                        
</dataForm:DataField>
                        
<dataForm:DataField Label="Title">
                            
<TextBox Text="{Binding Title, Mode=TwoWay}" />
                        
</dataForm:DataField>
                        
<dataForm:DataField Label="Marital Status">
                            
<TextBox Text="{Binding MaritalStatus, Mode=TwoWay}" />
                        
</dataForm:DataField>
                        
<dataForm:DataField Label="Gender">
                            
<TextBox Text="{Binding Gender, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }" />
                        
</dataForm:DataField>
                        
<dataForm:DataField Label="Salaried">
                            
<CheckBox IsChecked="{Binding SalariedFlag, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }" />
                        
</dataForm:DataField>
                        
<dataForm:DataField Label="Active">
                            
<CheckBox IsChecked="{Binding CurrentFlag, Mode=TwoWay,NotifyOnValidationError=True,  ValidatesOnExceptions=True }" />
                        
</dataForm:DataField>
                    
</StackPanel>
                
</DataTemplate>
            
</dataForm:DataForm.EditTemplate>
        
</dataForm:DataForm>

8. 打开EmployeeRegistrationWindow.xaml.cs :

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
public partial class EmployeeRegistrationWindow : ChildWindow
{
    
public Employee NewEmployee { getset; }
    
public EmployeeRegistrationWindow()
    {
        InitializeComponent();
        NewEmployee = new Employee();
        addEmployeeDataForm.CurrentItem = NewEmployee;
        addEmployeeDataForm.BeginEdit();
    }

    
private void OKButton_Click(object sender, RoutedEventArgs e)
    {
        addEmployeeDataForm.CommitEdit();
        
this.DialogResult = true;
    }

    
private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        NewEmployee = null;
        addEmployeeDataForm.CancelEdit();
        
this.DialogResult = false;
    }
}

9.  打开 EmployeeList.xaml.

10. 添加一个按钮叫‘addNewEmployee 放置在 DataPagerDataForm 中间

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
<!-- XAML --> 
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,0"> 
      
<Button x:Name="addNewEmployee" Width="90" Height="23" Content="Add Employee" Margin="4,0,0,0" Click="addNewEmployee_Click"/> 
</StackPanel> 

11. 打开 EmployeeList.xaml.cs.

12. 添加按钮事件

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
private void addNewEmployee_Click(object sender, RoutedEventArgs e) 
{
      EmployeeRegistrationWindow addEmp = new EmployeeRegistrationWindow(); 
      addEmp.Closed += new EventHandler(addEmp_Closed); 
      addEmp.Show(); 



13. 为EmployeeRegistrationWindow定义窗口关闭事件

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
void addEmp_Closed(object sender, EventArgs e)
{
    EmployeeRegistrationWindow emp = (EmployeeRegistrationWindow)sender;
    
if (emp.NewEmployee != null)
    {
        OrganizationContext _OrganizationContext = (OrganizationContext)(employeeDataSource.DomainContext);
        _OrganizationContext.Employees.Add(emp.NewEmployee);
        employeeDataSource.SubmitChanges();
    }

14. 打开OrganizationService.cs.

15. 添加下面的代码

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
public void InsertEmployee(Employee employee)
{
    
// Modify the employee data to meet the database constraints. 
    employee.HireDate = DateTime.Now;
    employee.ModifiedDate = DateTime.Now;
    employee.VacationHours = 0;
    employee.SickLeaveHours = 0;
    employee.rowguid = Guid.NewGuid();
    employee.ContactID = 1001;
    employee.BirthDate = new DateTime(1967318);
    
this.Context.AddToEmployee(employee);

16. 直接运行程序(Start Without Debugging )

17. 点击链接employee.
点击添加按钮,你可以添加employee , 并且因为使用了DataForm控件,原先的关于实体的所有字段都会应用验证提示。

clip_image012

4 授权

4.1 授权

1. 打开 OrganizationService.cs

2. 在需要添加权限设置的方法ApproveSabbatical添加 RequiresAuthentication 属性。这样就保证在服务器端只有符合权限的用户才能调用此方法。如果匿名用户点击了ApproveSabbatical 按钮,方法将不被执行。

[RequiresAuthentication()] 
public   void  ApproveSabbatical(Employee current) 

     
this .Context.Attach(current); 
     current.CurrentFlag  =   false
     
this .Context.SaveChanges(); 
}

3. 打开 EmployeeList.xaml.cs,添加下面的命名空间。

using  System.Windows.Ria.ApplicationServices; 

4. 当然,我们也可以在客户端进行身份验证,修改 approveSabbatical_Click 方法

确保只有登入的用户才能点击按钮,没有登录的要先进行登录操作。

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif Code
private void approveSabbatical_Click(object sender, RoutedEventArgs e)
{
    
if (RiaContext.Current.User.IsAuthenticated)
    {
        Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
        luckyEmployee.ApproveSabbatical();
        employeeDataSource.SubmitChanges();
    }
    
else
    {
        RiaContext.Current.Authentication.LoggedIn += Authentication_LoggedIn;
        
new LoginWindow().Show();
    }
}

private void Authentication_LoggedIn(object sender, AuthenticationEventArgs e)
{
    Employee luckyEmployee = (Employee)(dataGrid1.SelectedItem);
    luckyEmployee.ApproveSabbatical();
    employeeDataSource.SubmitChanges();
    RiaContext.Current.Authentication.LoggedIn -= Authentication_LoggedIn;

5. 运行程序。

6. 浏览employee 记录并点击‘Approve Sabbatical’ 按钮,会弹出登录窗口。

7. 输入帐号或者注册。
登录完成后我们可以点击按钮,实现其相关功能。

clip_image014

5 结束

本文由双宇翻译。原项目及文档地址

http://go.microsoft.com/fwlink/?LinkId=145481

 

转载请著明本文链接。

目录
相关文章
|
3月前
【Azure 应用服务】App Service 配置 Application Settings 访问Storage Account得到 could not be resolved: '*.file.core.windows.net'的报错。没有解析成对应中国区 Storage Account地址 *.file.core.chinacloudapi.cn
【Azure 应用服务】App Service 配置 Application Settings 访问Storage Account得到 could not be resolved: '*.file.core.windows.net'的报错。没有解析成对应中国区 Storage Account地址 *.file.core.chinacloudapi.cn
|
3月前
|
开发框架 监控 .NET
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
【Azure 应用程序见解】在Docker中运行的ASP.NET Core应用如何开启Application Insights的Profiler Trace呢?
|
存储 开发框架 .NET
ASP.NET中利用Application和Session统计在线人数、历史访问量
先来简单说一下ASP.NET中的Application和Session 下图是我们非常熟悉的Web应用程序的结构:
ASP.NET中利用Application和Session统计在线人数、历史访问量
|
.NET API 开发框架
Asp.Net Web API中使用Session,Cache和Application的几个方法
在ASP.NET中,Web Api的控制器类派生于ApiController,该类与ASP.NET的Control类没有直接关系,因此不能像在Web MVC中直接使用HttpContext,Cache,Session等,要使用的话,一般是从System.Web.HttpContext.Current静态对象引用HttpContext,从而使用Session等状态数据。
1179 0
|
Web App开发 XML 测试技术
asp调用.net xml web services
来源:http://www.cnblogs.com/notus/archive/2006/08/10/473000.html#2662503 (是不是实际上可以用这个办法调用任何xml web services呢?高人答一下)最近在做一个web services,由我来写文档。
826 0
|
C# Windows
怎样使用.NET RIA Services 创建 Silverlight Business Application(一)
HRApp 项目是.NET RIA Services MSDN  上的案例,一个使用Silverlight 3.0 + .Net RIA Service 构建的完整商业应用程序, 学习英文版的开发手册总是比较费力的,所以顺带着简略翻译一下,也有部分自己心得体会,不足之处还望大家多多交流。
1063 0
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
35 7
|
2月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
51 0
|
3月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
44 0