Linked In Twitter RSS

WPF Validation using Validation Application Block Part 1 – Server side

7. July 2009  · Comments (0)

If you are interesting to learn more about Validation Application Block you can always download Hand on Labs about VAB: http://www.microsoft.com/downloads/details.aspx?FamilyID=2C34A9CB-17CF-4AEC-8DE6-EEACBBB74413&displaylang=en

In these labs you will find very good explanation about using VAB integration with WCF, but what if you are manually creating proxy instead using add service reference?

In this article I will show you how to use VAB 4.1 with WCF and manually generated proxy.

My solution structure looks like this :

Picture1

I have created one project called DataContracts where all DataContract classes and Validation rules are defined. Code for that class looks like this :

 public class Customer

    {

        [StringLengthValidator(1, 25,

           MessageTemplateResourceType = typeof(Resources),

           MessageTemplateResourceName = "FirstNameMessage")]

        [NotNullValidator]

        public string FirstName { get; set; }

        [StringLengthValidator(1, 25,

          MessageTemplateResourceType = typeof(Resources),

          MessageTemplateResourceName = "LastNameMessage")]

        [NotNullValidator]

        public string LastName { get; set; }

        public string Nickname { get; set; }

        public DateTime BirthDate { get; set; }

        [ObjectValidator]

        public Address Address { get; set; }

 

        public Customer()

        {

            this.Address=new Address();

        }

    }

 

    public class Address

    {

        [StringLengthValidator(1, 50)]

        public string StreetName { get; set; }

 

        public int Number { get; set; }

        [DomainValidator("AL", "AK", "AS", "AZ", "AR", "CA", "CO", "CT", "DE", "DC", "FM", "FL", "GA", "GU", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MH", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "MP", "OH", "OK", "OR", "PW", "PA", "PR", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VI", "VA", "WA", "WV", "WI", "WY",

            MessageTemplate = "Value is not a valid US state two-letter abbreviation.")]

        public string USState { get; set; }

 

    }

I have manually created proxy class. It looks like this :

  public class CustomerClientProxy : ClientBase<ICustomerService>, ICustomerService

    {

 

        public string ProcessCustomer(DataContracts.Customer customer, string notes)

        {

            return Channel.ProcessCustomer(customer, notes);

        }

 

    }

In service contracts project I have defined interface that WCF will use. We must decorate method signature in interface with  validation attribute that define FaultContract for method.

We are using  ValidationFault class that is defined in VAB for error transporting to the client side.

  [FaultContract(typeof(ValidationFault))]

        string ProcessCustomer(

            Customer customer, [StringLengthValidator(1, 100,

                MessageTemplate = "The notes must be 1 to 100 characters long.")]

            string notes);

In web config file for WCF service we must add new behaviorConfiguration for Endpoint. ValidationElement is used to perform some validation actions on WCF before calling method on WCF.

<behaviorExtensions>
<add name="validation" type="Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF.ValidationElement, 
        Microsoft.Practices.EnterpriseLibrary.Validation.Integration.WCF, Version=4.1.0.0, Culture=neutral, 
        PublicKeyToken=31bf3856ad364e35" />
</behaviorExtensions>

On client side I have one standard WPF application with basic App.Config where is just defined ABC for WCF. (address, binding, contract)

I have bind client side textboxes on the form with my Customer class.  After that I have some code to catch exceptions throw by the server and show that exceptions in simple message box.

using (Proxy.CustomerClientProxy client = new Proxy.CustomerClientProxy())

            {

                try

                {

 

                    Customer cust=((Customer)this.DataContext);

 

                    client.ProcessCustomer(cust, "My message!!!");

                }

                catch (FaultException<ValidationFault> fex)

                {

                    StringBuilder builder = new StringBuilder();

                    builder.AppendLine("Validation error invoking service:<br/>");

                    foreach (ValidationDetail result in fex.Detail.Details)

                    {

                        builder.AppendLine(

                            string.Format("{0}: {1}<br/>", result.Key, result.Message));

                    }

 

                    MessageBox.Show(builder.ToString());

 

                }

 

                catch (Exception ex)

                {

                    MessageBox.Show(ex.StackTrace.ToString());

                }

            }

After I run my application and enter some incorrect values I get message box :

Picture2

 

Here is complete code :ValidationServiceWCF.rar

Reference : http://www.clariusconsulting.net/blogs/kzu/archive/2007/09/24/WhyweneedanEntLibStandaloneValidationApplicationBlock.aspx

Integrating silverlight 3 polling duplex with unity container

2. May 2009  · Comments (0)

These days everybody are using IOC container so I tried to integrate SL 3 Beta(MIX09) Sample chat application that represent how to work with polling duplex with Unity Ioc container. That sample chat application is available for download on codeplex.

After looking how to integrate Unity with Wcf I have founded few nice examples. All those examples are pretty much same.

To integrate Unity with Wcf we must create UnityServiceHostFactory and in markup of service say that service use that factory.

Polling duplex however has also DuplexServiceFactory. So how I integrate those two factories?

I have created all classes needed for UnityServiceHostFactory in UnityServiceHostFactory.cs file such as UnityServiceHost, UnityInstanceProvider and UnityServiceBehavior.

To make example more interesting I have also create IExample interface to inject this interface in service contructor like this:

public ChatService(IExample example)

        {

            examp = example;

            //Set up a stock update every 5 seconds

            this.stockTimer = new Timer(

                new TimerCallback(StockUpdate),

                null, 0, 5000);

        }

void StockUpdate(object o)

        {

            StockTickerMessage stm = new StockTickerMessage();

            //change this message to use method in interface

 

            stm.stock = "MSFT";

            stm.stock += examp.GetMessage();//calling method from injected interface

            stm.price = new System.Random().Next(20, 50);

            PushToAllClients(stm);

        }

In StockUpdate method in ChatService class in have called method GetMessage from Example class:

class Example : IExample

    {

        public string GetMessage()

        {

            return "Example";

        }

    }

In DuplexServiceFactory I have changed CreateServiceHost to use Unity container.

 protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)

        {

 

            UnityServiceHost host = new UnityServiceHost(serviceType, baseAddresses);

            UnityContainer unity = new UnityContainer();

            host.Container = unity;

 

 

            unity.RegisterType<IExample, Example>();

 

 

      

 

            CustomBinding binding = new CustomBinding(

              new PollingDuplexBindingElement(),

              new BinaryMessageEncodingBindingElement(),

              new HttpTransportBindingElement());

 

            host.Description.Behaviors.Add(new ServiceMetadataBehavior());

            host.AddServiceEndpoint(typeof(IUniversalDuplexContract), binding, "");

            host.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");

 

            return host;

        }

Now if I run my sample application I get error:

“The service type provided could not be loaded as a service because it does not have a default (parameter-less) constructor. To fix the problem, add a default constructor to the type, or pass an instance of the type to the host.”

Reason for this is because my Polling duplex class is decorated as singleton class

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]

    public abstract class DuplexService : IUniversalDuplexContract

    { 

and ServiceDescription.CreateImplementation and is hard-coded to look for a parameterless constructor.

But I want to make contructor injection so my service class must have contructor with parameter.

I have been remove [ServiceBehavior(InstanceContextMode=InstanceContextMode.SIngle)] and let Unity to return singleton instance of DuplexService class.

So I have put in web config file some code that Unity will use to return Singleton instance of DuplexService.

<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
                  Microsoft.Practices.Unity.Configuration" />
<unity>
<containers>
<container>
<types>
<type type="Microsoft.Silverlight.Cdf.Samples.Duplex.IUniversalDuplexContract,ChatWebApp"
mapTo="Microsoft.Silverlight.Cdf.Samples.Chat.ChatService,ChatWebApp"
>
<lifetime type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
    Microsoft.Practices.Unity" />
</type>
</types>
</container>
</containers>
</unity>

After that I have consumed code from web config in my application.

  UnityServiceHost host = new UnityServiceHost(serviceType, baseAddresses);

            UnityContainer unity = new UnityContainer();

            host.Container = unity;

 

 

            unity.RegisterType<IExample, Example>();

 

 

            UnityConfigurationSection section;

            section = (UnityConfigurationSection)ConfigurationManager.GetSection("unity");

            section.Containers.Default.Configure(unity);

I have tested this by calling IUniversalDuplexContract cont1 = unity.Resolve<IUniversalDuplexContract>() twice and comparing hash of two instances.

Hash was exactly same.That means that  Unity returns singleton instance of ChatService class.

I hope this will help.

Demo project : DuplexWithUnity.rar

Silverlight chat application using WCF full duplex

25. February 2009  · Comments (7)

Last week I have been started to read about full duplex wcf and his implementation in silverlight applications.I have read tons of articles on MSDN and tons of blog and forum posts.

Recently I have found solution for chat application on this blog http://silverbling.blogspot.com/2009/01/using-pollingduplexhttpbinding-for.html 

so I have little modified that application but it is basically same application.This application is based on this blog post of Dan Wahlin :

http://weblogs.asp.net/dwahlin/archive/2008/06/16/pushing-data-to-a-silverlight-client-with-wcf-duplex-service-part-i.aspx

Everything that you need to know about building wcf full duplex application for silverlight you can find on msdn :

http://msdn.microsoft.com/en-us/library/cc645027(VS.95).aspx

and for accessing wcf duplex from silverlight client:

http://msdn.microsoft.com/en-us/library/cc645028(VS.95).aspx 

This application is also based on same articles above.This is simple chat application that has no chat rooms.Same concept you can use for developing multiplayer online silverlight games.

If you want to modify this application to add rooms you can look some useful pattern for that  List-Based Publish-Subscribe  :

http://msdn.microsoft.com/en-us/library/ms752254.aspx

What I have get when I have finished project looks like this :

Ielook1

Only thing that you need to do to make this project work for you is to change url of your wcf web service in page.xaml.cs .

this.pusher = new PushDataReceiver(

                this.processor,

                "http://localhost.:5433/SilverlightChatDuplexService.svc",

                "Silverlight/ISilverlightChatDuplexService/InitiateDuplex",    // The Wcf function or action.

                "");

 

Demo project : SilverlightChatSource