Click here to Skip to main content
15,860,859 members
Articles / Web Development / IIS

WCF by Example - Chapter XIV - Validation & Exception Management

Rate me:
Please Sign up or sign in to vote.
5.00/5 (10 votes)
25 Oct 2012CPOL10 min read 118K   67   40
WPF Validation using the IDataErrorInfo interface combined with Validation attributes
PreviousNext
Chapter XIIIChapter XV

The Series

WCF by example is a series of articles that describe how to design and develop a WPF client using WCF for communication and NHibernate for persistence purposes. The series introduction describes the scope of the articles and discusses the architect solution at a high level. The source code for the series is found at CodePlex.

Chapter Overview

This is a two part chapter that covers the validation in WPF views and the management of business exceptions and warnings in the client side. For the validation topic, we will discuss how to provide comprehensive validation functionality all the way from the UI layers back to the server side, for the warnings and exceptions, the application will provide a customised exception handling mechanism for both client exceptions and business exceptions returned by the server methods; for the business notifications we will put in place a nice and slick notification feature that uses balloon notification messages in the Windows Task Bar.

Validation - DTO Implementation

We haven't covered validation in WPF in the series so far, maybe the reason for so it is to do with the fact that WPF validation is not that straight forward. We are going to describe what we consider to be a comprehensive solution given our application design. The eDirectory's solution is a hybrid one where a rich UI experience is provided but the validation code is not placed in the business entity, instead the DTO class is used for that purposes. In a nutshell, the following is an example of the type of validation functionality that is achieved in this manner:

Image 3

In order to provide the above functionality, the following steps are required:

  • The DTO class needs to inherit from a new base class: ValidatorDtoBase
  • DataAnnotation attributes are added to the DTO properties for validation purposes
  • XAML Binding needs to be amended with the following:
    1. Mode = TwoWay
    2. ValidatesOnDataErrors = True
    3. Validation.ErrorTemplate is set to the validationTemplate
  • Command buttons can bind to the IsValid property in the DTO for enabling/disabling purposes

As an example of how the DTOs will look after the above indicated changes, the CustomerDto looks like:

Image 4

And the following is a section of the XAML that was changed:

Image 5

And the last change is in the ViewModel so the Save button is enabled only when there are no validation errors:

Image 6

Validation Design Discussion

Before we continue, let's stop for a second to discuss what goals we tried to achieve with the above mentioned solution:

  • Follow the DRY principle
  • Easy to test
  • It should be possible to execute the validation both in the server and the client side

Regarding the DRY principle, on paper, the business entity should be responsible for the business validation, in the case of the eDirectory Customer class, for example, the First Name field is not nullable and cannot be longer than 50 chars. This is a classic example of validation that should be defined on the entity itself. It is feasible placing this validation on the entity but it generates a sort of crude validation solution where the client needs to call the server to find out if there is validation errors. On some projects, this is acceptable and it may result in being the best approach as it facilitates testing and rapid development.

The eDirectory application proposes a solution where simple validation can be declared in the DTO object so WPF validation can be used in the client side, the entity can also use this validation in the server side. We are basing this solution in the following articles:

Attributes-base Validation in a WPF MVVMIn this article, the IDataErrorInfo interface is used in combination with validation attributes in the ViewModel classes. We used the logic in the back-end to retrieve validation attributes and getters using LINQ queries. This concept was originally covered on the WPF Validation with Attributes and IDataErrorInfo in MVVM post
Automatically validating business entities in WPF using custom binding and attributesThis is an interesting article by Sandrino Di Mattia based on the work done by Phillipp Sumi on WPF custom binding. In this solution, a custom WPF binding is used for validation purposes, the eDirectory solution is very similar but it is developed around standard classes without requiring additional implementation. Still, it is a very good article.
Validation in Windows Presentation Foundation This is a four year old article that still applies, it is surprising how little things have changed since then, maybe Microsoft is trying to say to all of us that is time to move to the mighty Silverlight Smile
Implementing Data Validation in Silverlight with INotifyDataErrorInfoThis article covers the use of INotifyDataErrorInfo in Silverlight. It is a good article, discussing the limitations of the IDataErrorInfo interface and covering some of the internals of how controls interacts with the validation code.

Before we move on, if you are one of those that like DDD and find it frustrating to locate the validation outside the business entities, it may be the time to look at frameworks that resolve this type of issue in a better way:

IDataErrorInfo & Validation Attributes Implementation

Image 8

The eDirectory solution is based on the proposed idea on the WPF Validation with Attributes and IDataErrorInfo interface in MVVM post and it states:

WPF provides validation infrastructure for binding scenarios through IDataErrorInfo interface. Basically, you have to implement the Item[columnName] property putting the validation logic for each property in your Model (or ModelView) requiring validation. From XAML, you need to set ValidatesOnDataErrors to true and decide when you want the binding invoke the validation logic (through UpdateSourceTrigger). Then idea is to generalize the validation logic in IDataErrorInfo.Item[] using the validation attributes in System.ComponentModel.DataAnnotations assembly.

So we can have a new base class that inherits from DtoBase and implements the IDataErrorInfo interface so the WPF control can be notified if there was a validation error. The base class delegates to an instance of DataErrorInfo which is responsible for gathering the properties that are tagged with validation attributes and invokes the validation when the IDataErrorInfo methods are executed.

Image 9

It is worth noting that both the ValidatorDtoBase and DataErrorInfo implement the IDataErrorinfo interface and that the first one merely delegates into the second class when the methods are invoked.

Image 10

There is one aspect on this class that can be improved in terms of performance, your Dtos will not change at run time so it probably makes sense to store the validator and property maps the first time that they are created. This will result in a performance improvement although you will have to watch out for synchronization issues and locking.

Server Side Validation

As we indicated at the start of this chapter, one of our goals is to be able to check for validation errors at the server side as well. With the proposed solution, it is relatively easy to achieve this requirement. For example, when the Customer.Create method is invoked, the following code has been added:

Image 11

The ValidateOperation method is declared in the base class: EntityBase, this method checks for validation errors in the DTO, throwing a business exception if any error is found:

Image 12

XAML Error Templates

WPF provides very basic support for validation errors on the views, however with some few changes, we can provide a richer experience. Our solution provides three different mechanisms: red border around the textbox control, validation error symbol and tooltip.

Image 13

For the red border and the validation error symbol, a control template was created named validationTemplate, for the tooltip a custom style was created for the TextBox control. Both declarations were added to Application.resources at the App.xaml file.

For the tooltip to be shown, no further action is required. However, we need to indicate in each control that we want to use the validationTemplate in the XAML. You may prefer to move this template to an style instead, the following article explains how to do it: IDataErrorInfo, Error Templates and WPF.

The XAML for the template and style is as follows:

Image 14

Business Exception Management

We have covered in the previous chapters business warnings and exceptions in the server side, this section of this chapter covers for the client side, specifically how the client application notifies the user of those events. We are going to display a modal screen indicating the user of any exception and ensuring that the client application stops any processing. For the business warnings, instead, a notify icon will be available that will inform the user using info balloons on the Windows taskbar.

Trapping All Exceptions in a WPF Application

It is relatively easy to catch all unhandled exceptions in WPF:

Image 15

The handler implementation creates a new Notifier view and sets the Handled property to indicate to the application that the exception was managed.

Image 16

The view is quite simple, a left section for an image, the right panel is used for displaying the exception details. Couple buttons permit to copy the whole exception and call stack to the clipboard and close the window.

Image 17

There is nothing special regarding the new view and controller that we haven't seen before:

Image 18

At this point, we have a new mechanism that ensures all exceptions are well managed, for example, if an exception was to be generated during the client processing, the following screen is displayed:

Image 19 Image 20

Business Exceptions - Client Implementation

We need to leverage the new ExceptionNotifier with the Business Exceptions retrieved from the server responses. In first place, we need to revise the code at the ServiceAdapterBase class, the ExecuteCommand is the correct location for adding the new functionality. Currently the method looks like:

Image 21

We just need to call the new ExceptionNotifier implementation, a first implementation could be something as follows:

Image 22

We don't need to explain why an ExceptionNotifierViewModel instance is created, however the next line is critical in the implementation. Without it, the client does not know that an exception took place when calling the server, throwing an exception ensures that the client processing is halted. The SuspendProcessException is needed as the following changes are done to the Application Dispatcher Unhandled Exception method:

Image 23

Dependency Injection - Testing Implementation

After the above changes, if we execute the tests we notice that all of them are passing. The fact is that our coverage is not that good; we need a new test that causes a server business exception. The "CreateDuplicate" test does exactly so, if the test is executed the following window is displayed:

Image 24

This is obviously a problem, DI can help to resolve this issue. We need to encapsulate the business exception handling on a sort of abstract service and then provide a different implementation when the tests are executed. We need to take the following steps:

  • Create a new interface: IBusinessExceptionManager
  • Amend the ClientServiceLocator so an instance of the new interface is exposed
  • Use the new exposed interface in the ServiceAdapterBase ExecuteMethod
  • Create a new implementation of the new interface: BusinessException Manager
  • Add another implementation of the interface on the Test project
  • Modify Spring.Net configuration files

So the ServiceAdapterBase now looks like:

Image 25

The client implementation then is:

Image 26

The test implementation then is:

Image 27

Now, if the tests are executed, all of them pass including the new one:

Image 28

Business Warning Management

We now have a comprehensive mechanism for managing application and business exceptions, but we also need to work out a way for notifying for business warnings. Having dialog windows for warnings could annoy users, so instead we will use a sort of balloon notification running on the Windows Task Bar. For this purpose, we are using the WPF NotifyIcon project. The following steps are required to provide this functionality:

  • Create a new interface: IBusinessWarningManager
  • Add a new service WarningManager to the ClientServiceLocator class
  • Change the ServiceAdapterBase class so it uses the new service
  • Create new BusinessWarningManager class
  • Amend the Spring.Net configuration file to setup the WarningManager

The BusinesswarningManager implementation is as follows:

Image 29

It is worth noting how relatively easy is to invoke the TaskbarIcon in the above code. Then we need to change the ServiceAdapterBase to invoke the new method in the BusinessWarningManager:

Image 30

When a notification is received on the client side, a notification is automatically displayed on the Windows Taskbar:

Image 31

As we saw with the exception manager, we need a test implementation of the warning manager:

Image 32

Chapter Summary

Validation in WPF could be cumbersome sometimes, in this chapter a comprehensive solution using Validation attributes was presented that permits to execute the same validation both in the client and server side thus providing easy testing even when the validation logic is not located at the business entities.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Ireland Ireland
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWPF_WCF_Textbox Validation Pin
Member 1112568718-Dec-15 1:20
Member 1112568718-Dec-15 1:20 
Questionasp.net MVC project example Pin
Jose Campos11-Apr-12 12:21
Jose Campos11-Apr-12 12:21 
AnswerRe: asp.net MVC project example Pin
Enrique Albert11-Apr-12 13:27
Enrique Albert11-Apr-12 13:27 
AnswerRe: asp.net MVC project example Pin
Enrique Albert15-Apr-12 6:38
Enrique Albert15-Apr-12 6:38 
GeneralMy vote of 5 Pin
Manoj Kumar Choubey27-Mar-12 21:24
professionalManoj Kumar Choubey27-Mar-12 21:24 
QuestionException handling Pin
DotNetDev201626-Mar-12 19:09
DotNetDev201626-Mar-12 19:09 
AnswerRe: Exception handling Pin
Enrique Albert27-Mar-12 4:22
Enrique Albert27-Mar-12 4:22 
GeneralHats off - 5/5 Pin
sreejith ss nair14-Jan-12 14:09
sreejith ss nair14-Jan-12 14:09 
GeneralMy vote of 5 Pin
sreejith ss nair14-Jan-12 14:08
sreejith ss nair14-Jan-12 14:08 
GeneralRe: My vote of 5 Pin
Enrique Albert15-Jan-12 22:44
Enrique Albert15-Jan-12 22:44 
GeneralMy vote of 5 Pin
toantvo24-Aug-11 16:45
toantvo24-Aug-11 16:45 
GeneralRe: My vote of 5 Pin
Enrique Albert7-Sep-11 2:46
Enrique Albert7-Sep-11 2:46 
QuestionWCF Callbacks Pin
MikaelHild5-Aug-11 1:53
MikaelHild5-Aug-11 1:53 
AnswerRe: WCF Callbacks Pin
Enrique Albert7-Aug-11 17:05
Enrique Albert7-Aug-11 17:05 
QuestionFew questions.. [modified] Pin
Member 195080930-May-11 17:41
Member 195080930-May-11 17:41 
AnswerRe: Few questions.. Pin
Enrique Albert28-Jul-11 19:56
Enrique Albert28-Jul-11 19:56 
AnswerRe: Few questions.. [modified] Pin
Enrique Albert6-Oct-11 2:48
Enrique Albert6-Oct-11 2:48 
GeneralRe: Few questions.. [modified] Pin
DotNetDev20169-Oct-11 5:24
DotNetDev20169-Oct-11 5:24 
GeneralRe: Few questions.. [modified] Pin
Enrique Albert9-Oct-11 15:48
Enrique Albert9-Oct-11 15:48 
QuestionQuestion on validation Pin
tyzh24-Mar-11 9:13
tyzh24-Mar-11 9:13 
AnswerRe: Question on validation [modified] Pin
Enrique Albert24-Mar-11 23:06
Enrique Albert24-Mar-11 23:06 
GeneralRe: Question on validation Pin
tyzh25-Mar-11 5:50
tyzh25-Mar-11 5:50 
GeneralRe: Question on validation [modified] Pin
Enrique Albert25-Mar-11 14:50
Enrique Albert25-Mar-11 14:50 
GeneralRe: Question on validation Pin
Enrique Albert25-Mar-11 22:26
Enrique Albert25-Mar-11 22:26 
GeneralRe: Question on validation Pin
tyzh30-Mar-11 9:33
tyzh30-Mar-11 9:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.