Saturday, November 01, 2008

mp3 metadata


iPhone music is pretty cool isn’t it. Specially there are lots of free mp3’s out there. It is only inconvenient though to download an mp3 and find that iPhone have blank author name, album and song title. Pretty much the only thing that has a value if the mp3 file name, sounds common, eh? Well I found a nice tool that enabled a geek like me and probably like yourself to edit the mp3 tags from the command line, don’t you just like the command line?

This tool is called Id3, and can be found at
http://home.wanadoo.nl/squell/id3.html

This page also contains a bunch of very useful commands for this tool and the one I certainly use the most is

for %x in (*.mp3) do id3 -a "MyArtist" -l "AlbumName" -g "MyGenre" -t"%f" %x

This command will iterate through my music and change the artist, album name and genre to the ones I specify and then use the file name as the title.

I do this with the music I download off of the internet and they usually lack title, artist and/or album



Thursday, October 30, 2008

Multithreading and events



Don't you just love Multi-threading, well, I love to see my processor being efficiently used and close to at least 70% utilization. even though threads are dangerous however, using threads carefully will allow your user interface to always be responsive.
Nowthat, we will live with threads, those threads will certainly need to talk to the user interface thread. There are many ways for them to start chit chatting and my prefered way is events.
In this mechanism, a thread will raise an event and anyone who is subscribed to this event will receive the event data and will have a chance to process it.
Here is how to do that.
Let's say you have a calls called "Communicator" which will be processed in a thread and need to raise an event when the thread is done. what you need to do is
1- Define a delegate and an event as follows
//Delegate
public delegate void AlertSentHandler(object sender, SentAlertEventArgs e);
//Event
public event AlertSentHandler AlertSent;
2- Raise the event at the proper time as follows
onAlertSent(this,new SentAlertEventArgs(DateTime.Now.ToString()));
3- Since you are using a helper function called onAlertSent then you need to write it as follows
Protected void onAlertSent(object sender, SentAlertEventArgs e)
{
if (AlertSent != null)
AlertSent(sender, e );
}
The onAlertSent method is checking if the delegate is not null (There are subscribers to the event) and then call the delegate itself as shown above.

Now this event is sent because someone will probably care that the thread is done. those who care that the thread is done should subscribe to the event. To subscribe to this event simply subscribe as follows
cm.AlertSent += new Communicator.AlertSentHandler(cm_AlertSent);
and that is...!!!!!
Note: The above topic is different from serializing the threads (incorrectly called Synchronizing the threads). When you need threads to wait for each others you may want to use the serialization techniques, one of them is the ManualResetEvent
which you may declare like this

static ManualResetEvent threadSerializer = new ManualResetEvent(true );
and make your threads WaitOne like this
threadSerializer.WaitOne();
and set and reset like this
threadSerializer.Reset();
//Do thread work
threadSerializer.Set();
There is a complete and good article about this type of serialization techniques in these links

Wednesday, October 29, 2008

My Notes from "About Face" Book

As I am reading this book called "About Face" I remember David Platt's quote about blindly implementing a customer's requirement in software.
He is saying "Imagine a patient who visits his doctor with a horrible stomachache. "Doctor," he says, "it really hurts. I think it's my appendix. You've got to take it out as soon as possible." Of course, a responsible physician wouldn't perform the surgery without question. The patient can express the symptoms, but it takes the doctor's professional knowledge to make the correct diagnosis."

About Face book is saying

Current software, websites interface routinely
1- Make users feel stupid
2- Cause users to make big mistakes
3- Require too much effort to operate effectively
4- Don't provide an engaging or enjoyable experience

To those who do not have a design step I'd say
"You can not effectively design a house after construction begins"

Tuesday, October 14, 2008

Unhandled Exception

As I am working towards my master in information technology from Harvard university here in Cambridge, I attend a class currently taught by David Platt . The previous week assignment was about exceptions and I didn't know that there were two types of global exceptions that you can catch.

I used to know and use the event

Application.ThreadException +=
new System.Threading.ThreadExceptionEventHandler(
Application_ThreadException);

I just learned that this is not necessarily going to catch all unhandled exceptions, it will only catch all unhandled exception that occur in the UI thread.

If you really want to handle all unhandled exceptions then you need to broaden your scope and implement the domain unhandled exception event as follows.

AppDomain.CurrentDomain.UnhandledException +=
new UnhandledExceptionEventHandler(
CurrentDomain_UnhandledException);

I used to know about both events but didn't really know the difference until I learned about them from my TA (Kevin).

Go to this blog for more details


Have fun catching exceptions.

Thursday, October 09, 2008

Service-Based Database

If you still like those good old days of having your database file shipped with your application instead of relying on a SQL server be installed at the client machine, then you may want to add a SQL Server Express Database to your application. It is still possible to add a file based database to your application which Microsoft calls Service-Based Database [I don't think anyone knows why is it called this] but anyway, you can add it and that's what matters.

You can add the database by right click your project and select add item, then select data from the categories box and then select Service-Based Database as per the screen shot below.


However, if you do so, you may be challenged by the error message

Failed to generate a user instance of SQL Server due to a failure in
starting the process for the user instance. The connection will be
closed.

To solve this problem you really wanna make sure you have an administrator user on your machine. it seems you must start your visual studio as an administrator rather than any other user to be able to add this database to your solution.

To do so and start your visual studio as an administrator, right click your visual studio short cut and select run as as per the screen shot below












When you do so, you will get another dialog box that will ask you to type the name of the administrator user and the password. type the administrator user account and password.



Now don't tell me I am already an administrator on my machine!! doesn't work. the user name has actually to be called "Administrator" if you're an administrator on your machine in the administrators group that doesn't help. you ask why? I don't know.

If your machine does not have an administrator user called Administrator, then create that user and add it to the administrators group so that you can type that name in the dialog above.

Some people reported that this solution worked with them


HTH

Monday, September 29, 2008

Object Identity (Make Object ID)

In Visual Studio for C# there is this cool feature (Make Object ID), which allows you to assign an ID to the object you're debugging. it is very important to note that the object has to physically exist before you can assign an ID to it. so, you can not make this at design time. Even at run time you can not create the ID before the object has been created.

Here is how to use this cool feature given the following program.

            StringCollection ls = new StringCollection();
            ls.Add("ayman");
            ls.Add("ayman");

            foreach (string ss in ls)
            {
                MessageBox.Show(ss);
            }

The foreach loop above declares a string called ss. this ss is not the same ss every time a loop cycle is created. to enjoy the pleasure of seeing this fact, you can set a break point at the foreach line, and then when the debugger stops at the foreach line click F10 once so that ss is created and then hover over the variable ss. at this time, right click and choose "Make object ID" as per the picture below (notice that the debugger has executed the foreach line already and is about to enter the foreach block)



There is also delete object Id if you care to use it.

Friday, September 12, 2008

SCSF Events (One firer and multiple (Not wanted) subscribers)

So when working with SCSF you may face a problem like this.

You have built two views as part of a module (View1 and View2). View1 fires an event that View2 is  subscribed to. this all seems very legal until now. but what if View2 and View2 are loaded and displayed more than one time. now comes the illegal part. every time any of the View1 fires the event, all instances of View2 will receive it and react to it.

To illustrate it even further, assume you have built a hospital application that consists of two views. SearchView and DisplayView. the search view allows the user to search for a patient by specifying part of the patient name. but the SearchView does not display the search result, it is the DisplpayView that displays the results after receiving the Event showResults. now when the user types part of the patient name and click search, the event ShowResults will be raised and DisplayView will receive it. DisplayView will use the EventArgs to find the patient and then display him/her. the problem happens if you loaded two of the SearchView and two of the DisplayView. now when you type part of the paient name in any of the SearchView loaded and click Search, both of the loaded DisplayView will receive this event and will display this patient.

The solution to this problem is to make your module create a new work item every time it wants to add views. then add the views (SearchView and DisplayView) to this new work item.

when you fire the event you fire the event to the subscribers within the work item.
Here is how.
in your ModuleController.cs declare a new workitem as follows

WorkItem instancewi = new WorkItem();

Next, in the AddViews method add this new workitem to the WorkItems collection of the current item

instancewi = WorkItem.WorkItems.AddNew<WorkItem>();

now when adding views add then in this new workitem as follows

instancewi.SmartParts.AddNew<WhateverYourViewIs>();


now when firing an event, you should always be limiting the scope to the work item using PublicationScope.WorkItem enumeration and specifying the current workitem as follows

WorkItem.EventTopics[WhateverYourTopicIs].Fire(this,new EventArgs(WhaeteverWahtever), WorkItem, PublicationScope.WorkItem);

This way when you fire an event from one view, only the other views that were loaded with the same view will receive this event, since they are in the same workitem.
Hope that helps.

CAB/SCSF Visualizer

So I have an announcement to make: if you are a programmer working in 2008 and you don't know the basics of SCSF and the Visualizer, and I catch you, I'm going to punish you by making you peel onions for 6 months in a submarine. I swear I will.

The SCSF/CAB visualizer allows you to see interesting facts about your Workitems. I used it recently to debug and solve a problem in an application that I will be talking about in a next post. The visualizer allows you to see what your currently loaded work items are and shows the hierarchy that the object builder have built for you.

you can still see the same thing using the usual debugger as per the screen shot below, however the visualizer will make it easier for you since you do not need to stop and look for your root workitem to examine its contents. the visualizer will grasp the root workitem for you and will monitor it at all times. 



The screen shot below shows what the Visualizer screen looks like.


The visualizer shows you the root Workitem and its known collections (Items, UIextensionSites, etc..). using the WorkItems collections within the root workitem you will be able to examine what views are loaded and the relationships between your Views and workitems

one interesting thing I notices working with the visualizer is that you can double click a view and the Visualizer will show it to you in the WorkItem Visualization window. even more, it will allow you to interact with it.

To use the visualizer you need to download CAB Visualization Tool which is a dll from here

Copy this dll into your output folder (or add it as a reference in your Shell application) and then  change your app.config (shell.exe.config) by adding the following lines appropriately within the noted sections.


all you need to do after that is to start your application, magically the visualizer will appear and will show you the details of your CAB/SCSF application. neat eh?

Thursday, August 21, 2008

WCF Global Exception Handlers

in WCF if you handle an exception and convert it to a fault, this can travel thru the wire to the client. however you can not anticipate all exceptions that might be thrown by the service. In this case you may want to create a gloabl Exception handler that deals with any unhandled exception, convert it to a fault and send it through to the client.

The simple way to do this is by creating an attribute (ServiceExceptionHandlerAttribute) class and an error handler class (ServiceExceptionHandler) as follows

----------- the attribute --------------
using System.ServiceModel.Channels;
using System.ServiceModel.Description;


namespace Ayman.ExceptionHandling
{
public class ServiceExceptionHandlerAttribute : Attribute,IServiceBehavior
{
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(new ServiceExceptionHandler());
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
#endregion
}




------------ the error handler -----------------


using System.ServiceModel.Dispatcher;
using System.ServiceModel.Channels;



namespace Ayman.ExceptionHandling
{
public class ServiceExceptionHandler : IErrorHandler
{
public bool HandleError(Exception error)
{

return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
ValidationFault validationFault = new ValidationFault();
FaultException fe = new FaultException(validationFault, error.Message);
MessageFault mf = fe.CreateMessageFault();
fault = Message.CreateMessage(version, mf, fe.Action);
}
}
}





And now all you need to do, is to decorate your service with this attribute as follows

using Ayman.ExceptionHandling;
namespace Ayman.MyService
{

[ServiceExceptionHandler]
public class MyService : IMyService
{

}
}

Thursday, August 14, 2008

Forward your hotmail to gmail

When I got my iphone, I searched for a program to forward my hotmail to gmail since the iphone does not support hotmail. many services were present at this time but all of them require you to pay. finally I found this program which is called getmail. you can download it for free from this link

Thursday, August 07, 2008

Globalization

I have been reading through Globalization and wanted to post a quick summary on how to show your applications in many languages. The way it works is as follows You set your UI forms to localizable and change the culture in the form properties (ex. ar-EG) {for Arabic Egypt} and start playing around with the interface, change the position of the labels, change their text to display in arabic, etc... this interface will be stored associated with the culture that you selected (ar-EG).

.Net actually offers great features specially for arabic language or for Right to Left languages in general. .Net offers two new properties at the form level, if you change these properties, all the controls in the form will be affected.





The first property as per the screen shot above is called RightToLeft, when you set this property to Yes, all controls will be displaying text from Right to Left.

The other property is RightToLeftLayOut, when you set this property to True all the controls in the form will change their positions automatically to appear in the correct arabic way.

What you need to do next is, decide which culture you want to use by calling the following function to set the culture for your UI before the form is displayed.

System.Threading.Thread.CurrentUICulture = new System.Globalization.CultureInfo ("ar-EG")

note the above CurrentUICulture not CurrentCulture

the above line will instruct your application to show all the screens in arabic (ar-EG) in the same way you designed them when the culture was set to arabic (ar-EG) during design time.





Simple?

Friday, July 25, 2008

Egypt Vacation

So, and finally I got to enjoy a vacation after 4 years in Canada and the US. I spent most of the vacation in my condo in El-Rehab City http://www.alrehabcity.com and in Alexandria.

Here is some pictures.

























Build events and relative paths

When working with post/pre build events note the following.


1- The build event default path will be the project output path. Everything you write in the build event will be relative to the project output path. So for example. If your application is located at c:\project and it is configured to output things to bin\debug, then your project absolute output path is c:\project\bin\debug. If your output path is different, let’s say it is “..\bin\debug” then your project absolute output path is c:\bin\debug and everything you work on in the build events will start from c:\bin\debug.
The screen below shows how to set the project output path.















Now, when writing a build event paths in a build event, the relative path you use will be relative to that absolute output path which is c:\bin\debug. Ex A post build event like the following will copy the app.config file from c:\config to the output path

Xcopy ..\..\config\app.config *.* /c /y /q


basically the above statement is saying two levels up starting from the absolute project output path which is c:\bin\Debug , that will be C:\ and then it says go to Config folder and get the app.config.


Easy?


now assume you want to to copy a dll

From

C:\TFS1\ASC\ASC.CustomValidations\bin\Debug

To 
C:\TFS1\ASC.PM\ASC.PM.AccountServiceLibrary\bin\Debug 
and your project absolute path is C:\tfs1\ASC.PM\ASC.PM.AccountServiceLibrary\Bin\Debug


Here is what you need to type into the post build event 
xcopy ..\..\..\..\ASC\ASC.CustomValidations\bin\Debug\ASC.CalendarServiceAgent.dll.config


this is 4 levels up starting from the project absolute output path

that's 4 levels up from

C:\tfs1\ASC.PM\ASC.PM.AccountServiceLibrary\Bin\Debug

and that would be

C:\tfs1\


now go to ASC\ASC.CustomValidations\bin\Debug\ASC.CalendarServiceAgent.dll.config starting from c:\tfs1


and that would be 
C:\TFS1\ASC\ASC.CustomValidations\bin\Debug


and your target folder is the same as your absolute output path so you really do not need to type any path as a target path, so you just type *.*


Wednesday, July 23, 2008

ClickOnce for just about anything

Close your eyes, take a deep breath, click your heels three times, and say, "There's no better thing than ClickOnce"

With ClickOnce releasing a new version of your software is really a piece of cake, imagine the possibilites you have when you can push a new version to all your clients at once.

ClickOnce is great if you know how to use it and get around the limitations imposed in the Visual Studio IDE. using Mage and MageUI you can build unlimited ClickOnce deployment that can deploy any application easily and quickly. Please read on to know how to leaverage the full benefits of ClickOnce and overcome the Visual Studio limitation.

If you’re building a solution that contains multiple projects, then you will have a problem creating a ClickOnce deployment for it. ClickOnce will not collect the files of your other projects in the solution. In addition if you have any additional files to add to the deployment this is currently not possible with ClickOnce because the Application Files dialogue below will not let you add files to the deployment.




Luckily there is a way out of this using MageUI.exe which is Manifest Generation and Editing Tool, Graphical Client.
(You can read more about this tool here but you don’t really need to http://msdn.microsoft.com/en-us/library/xhctdw55(VS.80).aspx).
Using this tool you can build your ClickOnce deployment using any number of files located in a folder by following the steps below.

1- Build your solution and make all of your files in one folder (dll’s, exe, doc files, pictures, everything) ex. C:\bin
2- Decide what is the publish location that you want users to install your program from for the first time (ex. \\aali\Install)
3- Copy all the program binaries from c:\bin to the publish location under a bin folder ex. file://aali/install/bin
4- Delete *.application and *.manifest from the publish bin location (file://aali/install/bin) if you have any .application or .manifest files there, then your deployment will fail
5- Start MageUI by opening a Visual studio dos window (not the regular dos window) and type Magui.exe. When MageUI start click the first icon to the left in the tool bar. This icon will help you build an application manifest. The application manifest is an xml file that lists all the files in the folder file://aali/install/bin . To create this manifest. Type the publish bin folder in the “Application Directory” text box below (ex. file://aali/install/bin) and then click populate.



6- In the Name tab , enter a name for the application and a version






7- Save your manifest using the save button. The manifest has to be signed either with a stored certificate or a new certificate. Press the save button and when prompted click New as follows



When prompted enter any name for a certificate and then press Save and then Ok

Save the manifest file to the publish bin folder (file://aali/Install/bin)

8- Now you need to create a deployment manifest. The deployment manifest will have an .application extension and must be located in the publish folder (file://aali/install) directly not in the bin folder.
9- To create he deployment manifest click the second icon on MageUI tool bar and enter a name, and version number in the name tab

10- In the Application reference tab select your application manifest using the “Select Manifest” button and select the application manifest that was created in the previous step.

In the description Tab enter the product name, and then in the Deployment options tab enter the full path for the deployment manifest as follows



Save and sign this deployment manifest using the same certificate that you created in the previous step.
When saving the deployment manifest you need to save it to the publish folder not to the bin folder.

Now any user that points to file://aali/install/PC.application will get your application installed with all its files even if there were doc files, pictures, database files.
You can set the update options from the Update Options tab which is a self explanatory tab.

If you come up with a new version to your application you can repeat the same steps above to create a new deployment file with a higher version and updates will be done automatically to those who installed your application previously.

If you encountered any problem during the save, read the message carefully and you will be able to figure out what the problem is. I had to deal with two errors one was because I did not delete *.application and *.manifest and the other because I was trying to deploy .Net libraries which are installed already on the target computer (ex. System.data.dll or System.web.dll)

To automate this process using a batch file, here are the lines that should be in your batch file. Let's assume that this batch file is called UpdateDeployment.bat and it takes four parameters


Parameter %1 = Bin Source , %2 = Config Source, %3= Destination , %4 = Version

----------------- The batch file Begin ---------------------------
cls

mage -New Application -ToFile %3\%4\pc.exe.manifest -Name "PC" -um true -pub "Ayman Company" -Version %4 -FromDirectory %3\%4\

mage -Sign %3\%4\PC.exe.manifest -CertFile "c:\ClickOnce\PC.pfx"

mage -New Deployment -ToFile %3\PC.application -Name "PC" -Version %4 -AppManifest %3\%4\pc.exe.manifest -providerUrl %3\PC.application -i true

mage -Sign %3\PC.application -CertFile "c:\ClickOnce\PC.pfx"
------------------ The batch file end --------------------------

To call your batch file you will need to provide four argument as follows

UpdateDeployment.bat c:\bin c:\config \\aali 1.0.0.1


Prerequisites:
Prerequesites are located at C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages

if you have visual studio 2008 (if you can't find this location, try to guess it according to your installation of Visual studio and windows)

use bootstrap generation tool and create a prerequisite and then use Visual studio to create one boot strapper which will create one setup file that will install all the prerequisites.



And that will be it, hope that helps.

Validation Application Block

Starting to implement the Microsoft Validation Application block which I believe is somewhat cool, the following links gave me a good kick start








http://www.codeproject.com/KB/cs/VAB.aspx



http://msdn.microsoft.com/en-us/library/cc511770.aspx
http://www.codeproject.com/KB/WCF/WCFVAB.aspx

In general the validation application block allows you to add configurability to your service and UI validations. in this post I will talk briefly about what you need to do to implement VAB in your service and UI starting with the service.



Service Validation using VAB





So you have a service that contains some operations, to implement VAB you will have to modify every operation to make a call to

ServiceValidator.Validate(InsertRequest.AccountObject, MethodBase.GetCurrentMethod().Name)

all of the above is a custom code that you actually write, the ServiceValidator is a class that you should have built, and it containts the Validate method.

The first parameter to Validate is the object that you want its members validated. Here I want to mention one of the VAB limitations. the limitation is that you need to provide the object that you want to validate which is "InsertRequest.AccountObject", this object should be the direct parent of all the members (Fields, Properties) that you want to validate. VAB configuration will not let you start from "InsertRequest", it will only show one level down from the Type that you select in the configuration file and you can not drill down more. so if you start with InsertRequest, then you will only be able to set validation rules on AccountObject which is the direct child of InsertRequest class. but you can not set rules on members of AccountObject itslef.

To illustrate this in further consider the diagram below.























































In the diagram above, you see under the InsertAccount "rule set" you can choose the members of the parent type (Account). in case your parent type is InsertRequest you will not be able to access the grand children (AccountNameInternal), and this is why you will have to start with the parent object of the members you want to validate.








the validate method itself should call the enterprise library validate method, here is a sample code




public static class ServiceValidator
{
public static void Validate(T validationTarget, String ruleSet)
{
ValidationResults results = Validation.Validate(validationTarget, ruleSet);
if (!results.IsValid)
{
StringBuilder validationMsg = new StringBuilder();
int msgNumber = 1;
foreach (ValidationResult valResult in results)
{
validationMsg.Append("Service Reply " + msgNumber + ": ");
validationMsg.Append(valResult.Message + " {Key= "+ valResult.Key + ", Tag= " + valResult.Tag +"}\n");
msgNumber++;
}
throw new Exception(validationMsg.ToString());
}
}
}


the Validation class referenced above is located at
Microsoft.Practices.EnterpriseLibrary.Validation


when you want o send the validation result to the caller, you usually do that via Faults. so you need to send a Fault back to the caller.

the exception thrown in the code above will need to be captured at the service boundary and convereted to fault and this is the only way it can travel safely thru the wire back to the caller.

you can use srvcconfig and srvcmonitor applications to monitor what is actually travelling thru the wire.

the code below shows how to capture and convert the exception to a Fault.

public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
ValidationFault validationFault = new ValidationFault();
FaultException fe = new FaultException(validationFault, error.Message);
MessageFault mf = fe.CreateMessageFault();
fault = Message.CreateMessage(version, mf, fe.Action);
}

he above function receives your exception and converts it to a Fault and sends it over.

The best practice in handling Exceptions in the service is to handle the exception at the service boundary. A good way of doing this is to create an attribute as follows


public class ServiceExceptionHandlerAttribute : Attribute,IServiceBehavior
{
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
foreach (ChannelDispatcher dispatcher in serviceHostBase.ChannelDispatchers)
{
dispatcher.ErrorHandlers.Add(new ServiceExceptionHandler());
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
#endregion
}

the attribute references the class ServiceExceptionHandler which is implemented as follows


public class ServiceExceptionHandler : IErrorHandler
{
public bool HandleError(Exception error)
{
//ASCLogger.LogError(string.Format("Uncaught exception of type {0} was thrown. Message: {1}", error.GetType(), error.Message),true );
return true;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
ValidationFault validationFault = new ValidationFault();
FaultException fe = new FaultException(validationFault, error.Message);
MessageFault mf = fe.CreateMessageFault();
fault = Message.CreateMessage(version, mf, fe.Action);
}
}

Now if you decorate your service with this attribute you're all set in handling every single exception and converting it to a fault and passing it back to the caller.


Validating User Interface

To use VAB in the UI you need to add an ErrorProvider which comes with .Net and a ValidationProvider which comes with the enterprise library to your form. Attach the ValidtionProvider to the ErrorProvider and attach your control to the ValidationProvider.

Couple of things to note here.
1- UI and service can not share the same validation file if they do not share the data contracts. In your UI you will most probably have a service agent that copies the service objects in the UI. When you try to add the same type to the config file it will be refused.
Also there is a nice little trick about using the load assembly functionality when you add a new type to the validation config file. if you are like me irritated by the long list of objects that appears after you add an assembly, you can use this trick







after adding your assembly, select any object from the list and then press ok, then delete the object that you just added to the config file and then click to add a type again, you will now see the same diagram above but all the types will be in a collapse mode instead of an expand mode.

VAB will only help you validate simple things like text box, drop down. but if you have a grid for example, you will have to write a custom validation, which I did not like so much.