Introduction
We have seen how to validate in Silverlight using IdataErrorInfo. Here in this
article we will see how to validate any input field using RIA Services.
When I say RIA services, we will be using domain services and data annotation
attributes to validate the input field.
Setting Up Silverlight Project
Open Visual Studio and create a new Silverlight application; in my case
it is ValidationUsingRIAServices. So we will be provided two project one
ValidationUsingRIAServices which is our Silverlight application and the other
ValidationUsingRIAServices.Web which is our server application. One most
important point is to check Enable RIA service while creation of this project.
Lets follow a step wise procedure to implement validation using RIA Services
1. Lets put some input field to our MainPage.xaml so that it will look something
like:
2. Now its time for some database stuff. Lets choose any database and create a
table tblEmployee and it will have the following design.
3. For the very next step will be adding a ADO.NET Entity data Model to our
ValidationUsingRIAServices.Web once we will add the template the wizard will
guide us through to choose the database and corresponding table and finally we
will land up to with following scenario:
Just build the project so that when we add the domain service we will have
tblEmployee available to include.
4. Now add a new item called domain service class; in my case I have named it as
EmployeeService.cs. Once you add you will encounter following screen
From the screen we can see the entity tblEmployee is available to us to choose;
lets choose checkbox for tblEmployee and we can see there is another checkbox
"Enable editing" that is optional. Domain service automatically generate
functions for CRUD(INSERT,READ,UPDATE,DELETE) operation for the entity which we
have selected but out of 4 CRUD operation by default we get function for
extracting data from the same entity, other three gets generated when we select
enable edition option. Finally we need to make sure that we check the Generate
associated classes for metadata. Once we are done we will get EmployeeService.cs
class with following code automatically generated.
[EnableClientAccess()]
public class
EmployeeService :
LinqToEntitiesDomainService<DatabaseEntities>
{
//READ
public
IQueryable<tblEmployee>
GetTblEmployees()
{
return this.ObjectContext.tblEmployees;
}
//CREATE
public
void InsertTblEmployee(tblEmployee
tblEmployee)
{
if ((tblEmployee.EntityState !=
EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(tblEmployee,
EntityState.Added);
}
else
{
this.ObjectContext.tblEmployees.AddObject(tblEmployee);
}
}
//UPDATE
public
void UpdateTblEmployee(tblEmployee
currenttblEmployee)
{
this.ObjectContext.tblEmployees.AttachAsModified(currenttblEmployee,
this.ChangeSet.GetOriginal(currenttblEmployee));
}
//DELETE
public
void DeleteTblEmployee(tblEmployee
tblEmployee)
{
if ((tblEmployee.EntityState !=
EntityState.Detached))
{
this.ObjectContext.ObjectStateManager.ChangeObjectState(tblEmployee,
EntityState.Deleted);
}
else
{
this.ObjectContext.tblEmployees.Attach(tblEmployee);
this.ObjectContext.tblEmployees.DeleteObject(tblEmployee);
}
}
}
With this the domain service creation has created another class
EmployeeService.metadata.cs which looks like:
And inside that we can find codes which will look like:
public
partial class
tblEmployee
{
internal sealed
class
tblEmployeeMetadata
{
// Metadata classes are not meant to be instantiated.
private tblEmployeeMetadata()
{
}
public string
EmployeeAddress { get;
set; }
public
string EmployeeDepartment {
get; set; }
public int
EmployeeID { get; set;
}
public string
EmployeeName { get; set;
}
}
}
Lets put some dataannotation attributes to these field and lets make all the
field required. After we put required attributes the code will look like
public
partial class
tblEmployee
{
internal sealed
class
tblEmployeeMetadata
{
// Metadata classes are not meant to be instantiated.
private tblEmployeeMetadata()
{
}
[Required]
public
string EmployeeAddress { get;
set; }
[Required]
public
string EmployeeDepartment { get;
set; }
[Required]
public int
EmployeeID { get; set;
}
[Required]
public
string EmployeeName { get;
set; }
}
}
5. So we have completed all the server related work. Now we will move to
Silverlight Application. Lets create a class with the same name tblEmployee.
Lets make the class as partial class of tblEmployee. Here we are trying to
create a partial class of the same entity that is tblEmployee which we have
already defined in domain class.
public
partial class
tblEmployee
{
}
Finally to make it work we need to match the namespace of the metadata class
"EmployeeService.metadata.cs" with that of the class created in Silverlight
application project. Sp we will change the namespace of partial class created in
Silverlight application in match with that of metadata class in Silverlight web
application.
6. We need to add code for validation and after adding the class will look like
:-
namespace
ValidationUsingRIAServices.Web
{
public partial
class tblEmployee
{
public bool
ValidateEmployee(ValidationContext
validationContext)
{
//Clear Previous valiadtion.
ValidationErrors.Clear();
IDictionary<object,
object> dictionaryItems =
null;
ValidationContext
employeeValidationContext = new
ValidationContext(this,
validationContext, dictionaryItems);
ICollection<ValidationResult>
employeeValidationResults = new
List<ValidationResult>();
//Use tryValidateobject to validate
if (Validator.TryValidateObject(this,
employeeValidationContext, employeeValidationResults,
true) == false)
{
//Adding Validation result to
validation error
foreach (ValidationResult
validationError in employeeValidationResults)
{
ValidationErrors.Add(validationError);
}
return
false;
}
return true;
}
}
}
7. And Finally in MainPage.xaml.cs we need to create a property of
tblClassEmployee for binding it to the xaml. Here we need to refer the domain
services which we have created.And we need to bind the data so we will have code
something like
public
partial class
MainPage :
UserControl
{
EmployeeContext dataContext =
new EmployeeContext();
private tblEmployee
_newEmployee;
public
tblEmployee NewEmployee
{
get
{
return _newEmployee;
}
set
{
_newEmployee = value;
}
}
public MainPage()
{
InitializeComponent();
_newEmployee = new
tblEmployee();
employeeStackPanel.DataContext = NewEmployee;
}
private void
AddEmployeeButton_Click(object sender,
RoutedEventArgs e)
{
if (NewEmployee.ValidateEmployee(dataContext.ValidationContext)
== false)
{
return;
}
//Go Ahead and do something
}
}
8. At the end of the code to the button click event of the code I have called
ValidateEmployee which will validate the employee. And our XAML will look like
<StackPanel
x:Name="employeeStackPanel">
<StackPanel
Orientation="Horizontal"
Margin="0,10,0,0"
>
<sdk:Label
x:Name="employeeIDLabel"
Content="Employee
ID:"
Width="120"
Margin="5,0,0,0"
/>
<TextBox
Width="200"
Height="23"
Margin="5,0,0,0"
Text="{Binding
EmployeeID,
Mode=TwoWay}"
/>
</StackPanel>
<StackPanel
Orientation="Horizontal"
Margin="0,10,0,0">
<sdk:Label
x:Name="employeeAddressLabel"
Content="Employee
Address:"
Width="120"
Margin="5,0,0,0"
/>
<TextBox
Width="200"
Height="23"
Margin="5,0,0,0"
Text="{Binding
EmployeeAddress,
Mode=TwoWay}"
/>
</StackPanel>
<StackPanel
Orientation="Horizontal"
Margin="0,10,0,0">
<sdk:Label
x:Name="employeeNameLable"
Content="Employee
Name:"
Width="120"
Margin="5,0,0,0"
/>
<TextBox
Width="200"
Height="23"
Margin="5,0,0,0"
Text="{Binding
EmployeeName,
Mode=TwoWay}"
/>
</StackPanel>
<StackPanel
Orientation="Horizontal"
Margin="0,10,0,0">
<sdk:Label
x:Name="employeeDepartmentLable"
Content="Employee
Dept:"
Width="120"
Margin="5,0,0,0"
/>
<TextBox
Width="200"
Height="23"
Margin="5,0,0,0"
Text="{Binding
EmployeeDepartment,
Mode=TwoWay}"
/>
</StackPanel>
<StackPanel
Margin="100,10,0,0"
HorizontalAlignment="Left"
>
<Button
x:Name="AddEmployeeButton"
Width="100"
Height="30"
Content="Add
Employee"
Click="AddEmployeeButton_Click"
/>
</StackPanel>
</StackPanel>
9. And you are done When you will go and run the project the first screen which
you will encounter is
.
Once you will click on AddEmployeeButton you will face following screen .
Since in the Metadata class we have just used Required Attributes that is why we
are getting required validation only we can change that with our requirement. We
can have other attributes depending upon our requirement for example we can
place regular expression attributes to match, again we can restrict string
length of our input using StringLength attribute . I have changed few of them so
my metadata class looks like
internal
sealed class
tblEmployeeMetadata
{
// Metadata classes are not meant to be instantiated.
private tblEmployeeMetadata()
{
}
[Required(ErrorMessage="Employee
Address is Required")]
[StringLength(200,MinimumLength =
10,ErrorMessage = "Employee Address can't be less
than 10 characters")]
public
string EmployeeAddress { get;
set; }
[Required(ErrorMessage="Employee
Department should be given")]
[RegularExpression(@"^\d+$",
ErrorMessage = "Numbers are allowed only")]
public
string EmployeeDepartment { get;
set; }
[Required]
public int
EmployeeID { get; set;
}
[Required(ErrorMessage="Employee
name should be given")]
[RegularExpression(@"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$",ErrorMessage="Given
Employee Name is Not Valid")]
public
string EmployeeName { get;
set; }
}
Here we have restricted EmployeeDepartment to have numeric data only and
EmployeeName to have mail format and restricted length of employee address . So
now the screen will look like.
Here we have set a policy for Employee Address
Here we are matching the Employee Name with the mail format.
Employee Department can just accept numbers only.
Hope this will Help !!!!!.