WCF Services in Silverlight without using “Add Service Reference”

Some Intro:

Hello, I ‘m back again!!!!.  This post was prepared with motivation to the points that Miguel A. Castro, NetFXHarmonics and also Developer’s Dump mentioned. So to use WCF service efficiently, I won’t use “Add Service Reference” and configure WCF manually. You can already find a nice article on NetFXHarmonics but I just want to explain it in my way. Note that the example in this post is all generated by the use of NetFXHarmonics example so you can find better explanation in that blog.

Let’s get started:

First, we are starting our example by creating an “Empty Project” in Visual Studio 2008.  Then add a Class Library project to this empty project. And throughout the project we will need two main references which are “System.ServiceModel” and “System.Runtime.Serialization”. Note that this Class Library (Contact.Servivce) is our solution for implementation and contact definitions of WCF Service. In this as mentioned in NetFXHarmonics you can use seperate projects for implementation and contacts but I use them together for simplicity for now.  Then create Person.cs to use it to hold our datacontracts.

Person.cs:

using System;
using System.Runtime.Serialization;

namespace Contact.Service
{
    [DataContract(Namespace = Information.Namespace.Contact)]
    public class Person
    {
        //- @Guid -//
        [DataMember]
        public String Guid { get; set; }

        //- @FirstName -//
        [DataMember]
        public String FirstName { get; set; }

        //- @LastName -//
        [DataMember]
        public String LastName { get; set; }

        //- @City -//
        [DataMember]
        public String City { get; set; }

        //- @State -//
        [DataMember]
        public String State { get; set; }

        //- @PostalCode -//
        [DataMember]
        public String PostalCode { get; set; }

    }
}

Then  create interface IPersonService.cs.

using System;
using System.Collections.Generic;
using System.ServiceModel;
//+
namespace Contact.Service
{
    [ServiceContract(Namespace = Information.Namespace.Contact)]
    public interface IPersonService
    {
        //- GetPersonData -//
        [OperationContract]
        Person GetPersonData(String personGuid);

    }
}

And at the end implement those in PersonService.cs.

PersonService.cs:

using System;
using System.Collections.Generic;
using System.ServiceModel;
//+
namespace Contact.Service
{
    public class PersonService : IPersonService
    {
        //- @GetPersonData -//
        public Person GetPersonData(String personGuid)
        {
            return new Person
            {
                FirstName = "Huseyin",
                LastName = "Cakir",
                City = "Izmir",
                Guid = "F488D20B-FC27-4631-9FB9-83AF616AB5A6",
                PostalCode = "35500",
                State = "TR"
            };
        }
    }
}

Now we need a web site to host WCF Service we have created.  Create a web site called Service, delete Default.aspx as we don’t need and add “Contact.Service” as reference. You should see the “Contact.Service.dll” appears in the web site solution. Then prepare Person.svc as follows;

Person.svc:

 <%@ ServiceHost Service="Contact.Service.PersonService" %>

Then, it is time to prepare ClientAccessPolicy.xml as traditionally in WCF Services not to have some pain in future. If you don’t use access policy you will get the following error:

An error occurred while trying to make a request to URI ‘http://localhost:1218/Service1.svc&#8217;. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a cross-domain policy file and to ensure it allows SOAP-related HTTP headers to be sent. Please see the inner exception for more details.

ClientAccessPolicy.xml:

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from>
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>

And we almost done with the WCF Service but as a last issue we have to configure our web.config. I didn’t put it here since you can find it in my sample project but note that there exists some important points in that web.config.  First the <service.serviceModel> should be basicHttpBinding and than <compilation debug=”true”>. So our WCF should run now. You should run this WCF to see that you can access Person.svc. In my situation it was in http://localhost:1031/Service/Person.svc.

As you can see all the steps up to now are same with in manual .NET WCF.

Now it is time to create Silverlight Application. In Silverlight App. we are going to use IPersonService.cs and Person.cs again as follows;

IPersonService.cs:

using System;
using System.ServiceModel;
//+
namespace Contact.Service
{
    [ServiceContract(Namespace = Information.Namespace.Contact)]
    public interface IPersonService
    {
        //- BeginGetPersonData -//
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginGetPersonData(String personGuid, AsyncCallback callback, Object state);

        //- LoadPerson -//
        Person EndGetPersonData(IAsyncResult result);
    }
}


Person.cs:

using System;
using System.Runtime.Serialization;
//+
namespace Contact.Service
{
    [DataContract(Namespace = Information.Namespace.Contact)]
    public class Person
    {
        //- @Guid -//
        [DataMember]
        public String Guid { get; set; }

        //- @FirstName -//
        [DataMember]
        public String FirstName { get; set; }

        //- @LastName -//
        [DataMember]
        public String LastName { get; set; }

        //- @City -//
        [DataMember]
        public String City { get; set; }

        //- @State -//
        [DataMember]
        public String State { get; set; }

        //- @PostalCode -//
        [DataMember]
        public String PostalCode { get; set; }

    }
}

And at the endedit the Page.xaml.cs like this;

Page.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ServiceModel;
using Contact.Service;

namespace SilverlightApplication4
{
 public partial class Page : UserControl
 {
 public Page()
 {
 InitializeComponent();
 }

 private void Button_Click(object sender, RoutedEventArgs e)
 {
 BasicHttpBinding basicHttpBinding = new BasicHttpBinding();
 EndpointAddress endpointAddress = new EndpointAddress("http://localhost:1679/WebSite5/Person.svc");
 IPersonService personService = new ChannelFactory<IPersonService>(basicHttpBinding, endpointAddress).CreateChannel();
 //+
 AsyncCallback asyncCallBack = delegate(IAsyncResult result)
 {
 Person person = ((IPersonService)result.AsyncState).EndGetPersonData(result);
 this.Dispatcher.BeginInvoke(delegate
 {
 spMain.Children.Add(new TextBlock
 {
 Text = person.FirstName + person.LastName + person.City + person.State
 });

 });
 };
 personService.BeginGetPersonData("F488D20B-FC27-4631-9FB9-83AF616AB5A6", asyncCallBack, personService);
 }
 }
}

As you can see we use Async Pattern to call our functions is Silverlight-WCF service.

As a recap I used the same example with NetFXHarmonics to make it possible to understand it by looking both posts. But myself learned this access thanks to NetFXHarmonics.

Download Sample Solution

Thanks for your patience!
kick it on DotNetKicks.com

About these ads