metadevblog

Windows Phone 7 App Development

Archive for the ‘WCF’ Category

Silverlight Metro Theme

with 3 comments

The WP7 currently has a tiny market share so writing apps to target both the WP7 and the desktop using the same code base makes a great deal of sense to me.  Especially for tools such as Master Key which has as much validity (if not more) on the desktop as it does on my phone.

I picked up a copy of the Metro Theme from a project on Codeplex and copied one of the Master Key XMLA pages over.  It worked pretty well but in the end I’m left in the position of having to do a great deal of work to make the page fit into a browser window rather than the phone.

http://metrotheme.codeplex.com/

There are a number of issues.  Firstly the fonts and lines used to render on the WP7 screen look huge when viewed in normal Windows resolution; secondly the theme is incomplete and has missing features.  While all this can be fixed by modifying the theme it’s a lot of work.

Secondly, and obviously, the browser environment is significantly different to that of the WP7. The hardware back and close buttons have to be provided in Silverlight and handled in the browser. From a browser UX point of view these buttons would typically be at the top of the screen.  Handling ‘back’ is less of a problem as the browser supports this. However the browser also provides ‘forwards’ as well and the user can also pick an item from the navigation history and jump directly there, neither of which are possible in WP7.

Having experimented with directly porting the WP7 app and finding it a less than compelling outcome I searched around for the Silverlight theme to use.  After some experimentation I picked up a Window 7 theme that the Silverlight dev team released (see Tim Heuer’s blog http://timheuer.com/blog) and have used this as the basis for the Windows version.

The project template also provides a navigation framework which is really useful and this integrates into the browser navigation history providing back/forward support.

It was pretty simple to take a WP7 page and convert it to Win7, for the most part the XAML simply pasted directly and only needed to be lightly manipulated to fit.  Over the space of a couple of days I had pretty much replicated the App, however…

However, it was apparent pretty quickly that the integration into the browser navigation was not going to work, the history just kept getting bigger and worse I could jump forward when it was illogical to do so.  I spent a lot of time trying to make it work but in the end it was just too confusing from a UX point of view.  I switched it off and suddenly the navigation became a whole lot more logical as the framework is tabbed

image

The ApplicationBar in WP7 is a great little control and works really well on the phone.  It’s location at the bottom of the screen near to the where your fingers lay makes for a great UX. 

I considered briefly writing a version of this for Silverlight but decided against it as the more normal windows layout is better and the Ribbon interface is clean and well accepted.

In the end I decided that the simplest approach was to revert from having ApplicationBar based button back to a more traditional approach with the buttons embedded into the UI.  This is perfectly valid when there are so few buttons required to make the App work.

It was apparent as soon as I started to think about a Silverlight version of Master Key that combining the item selection and its content into a single page would be the best approach; so for WP7 the user is shown the Vault Entries as a list:

edit_vault

And when an item in the list is selected is is displayed on a separate screen:

edit_entry

This works really well – the UI is easy to use and quite clear in its intent.

Combining the two screens and modifying the UI slightly gives this screen:

image

Master Key on WP7 relies on the phone timeout kicking in to prevent unauthorised access, on my phone it’s set to a minute after which it will tombstone and the user has to re-enter the password to regain access to the information when the app is reactivated. 

In the browser environment this has to be done within the page by running a timer that will prevent access if there is no activity.  I’ve added a progress bar at the bottom of the screen – after 30 seconds of inactivity the page will close and revert to the login screen. Job done!

The core functionality of Master Key for WP7 has moved without change to the Silverlight version.  I’ve not had to touch a line of code in the data access layer to make it work and this includes the WCF service code (though to be fair I added the service reference to the new project and it auto-generated the appropriate code).

You don’t need to be too eagle eyed to see that the two vaults are the same – I simply loaded the demo vault into both versions of the App from the web service.

So the end result is that I now have a WP7 and Windows version of Master Key and the vault files are interchangeable between the two.  Also I now have a good idea as to how much additional effort has to be put in to convert between the two platforms.  I have a bit of work still outstanding to be able to launch the desktop version from the MasterKey service but I don’t anticipate this taking a lot of time.

One thing – I am pretty frustrated with myself for using the Windows 7 theme rather than Cosmopolitan as this is the closest the the WP7 Metro theme.  I was hoping I could simply swap themes but this failed on my first attempt to replace the Windows 7 theme. I’ll have to spend some time working this out when I have a chance.

Advertisements

Written by metadevblog

July 13, 2011 at 10:50 am

Posted in Master Key, Silverlight, WCF, WP7

Master Key published!

leave a comment »

While I’ve not blogged the event in a timely manner my app Master Key was published on 10th May a couple of days after I submitted it.  I’m pretty pleased with this!

I’ve used the app since it was in early development and am now working on V2.0 based on my own user feedback which I hope to upload over the next week or so.  I’ve extended the functionality now beyond simply having the password associated with a caption to include an identity and some additional notes.

I’m up to 20 different entries now, it’s really come as quite a surprise as to how many different identities I have and it’s really great having all the info in one secure place.

As I have blogged previously the phone can easily connect to a web service.  I’ve used this approach to provide a backup and restore facility for the Master Key vault.  As the service is provided as an HTTP endpoint it can run anywhere the phone can access.

When the phone is attached by it’s cable to a PC it has access to the Ethernet the PC is connected to as as the HTTP endpoint can be easily exposed on the network it becomes quite simple to make a connection without having to have any complex security or exposure to the wider internet.

Written by metadevblog

June 5, 2011 at 1:11 pm

Posted in Master Key, WCF

WP7 accessing a Windows Service DataService

leave a comment »

This application took 2 minutes to write…

Now that I have demonstrated how Silverlight can access a DataService that is hosted by a WindowsService the final example is to show that it will work on a WP7.

I created a new Windows Phone application and added a Button and Textbox.

I added a Service Reference to the DataService to the Solution.

Finally I pretty much copied the code from the Silverlight application in the previous post.

using WPService.DataService;
using System.Xml.Linq;

namespace WPService
{
    public partial class MainPage : PhoneApplicationPage
    {
        DataServiceClient dataService = null;

        // Constructor
        public MainPage()
        {
            InitializeComponent();

            dataService = new DataServiceClient();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                dataService.GetDateTimeCompleted += new EventHandler<GetDateTimeCompletedEventArgs>(dataService_GetDateTimeCompleted);
                dataService.GetDateTimeAsync();
            }
            catch (Exception ex)
            {
                textBlock1.Text = string.Format("Error occurred: {0}", ex.Message);
            }
        }

        void dataService_GetDateTimeCompleted(object sender, DataService.GetDateTimeCompletedEventArgs e)
        {
            try
            {
                XElement xResult = (XElement)e.Result;

                string date = xResult.Element("Date").Value;
                string time = xResult.Element("Time").Value;

                textBlock1.Text = string.Format("The date is: {0}\nThe time is: {1}", date, time);

            }
            catch (Exception ex)
            {
                textBlock1.Text = string.Format("Error occurred: {0}", ex.Message);
            }
        }
    }
}

 

I clicked the Button!

image

Says it all!

Written by metadevblog

March 29, 2011 at 10:00 pm

Posted in WCF, WP7

Tagged with , ,

Using Silverlight with a Windows Service – Part 2

with one comment

In order to get the Silverlight version of the application to work the Windows Service has to be modified so that it can provide the necessary Silverlight clientaccesspolicy.xml file or Flash policy file crossdomain.xml from root domain of the service.

This is accomplished by adding a WebService to the WindowService running on the same port as the existing Data Service and using a URL rewriter to provide the correct xml file to the Silverlight application.

First add empty IWebService.cs and WebService.cs classes.

The IWebService.cs should be replaced with this code:

using System.ServiceModel;
using System.IO;
using System.ServiceModel.Web;

namespace ConsoleApplicationWCF
{
    [ServiceContract]
    public interface IWebServer
    {
        [OperationContract, WebGet(UriTemplate = "ClientAccessPolicy.xml")]
        Stream GetClientAccessPolicy();
    }
}

 

Note: You will need to add a reference to System.ServiceModel.Web which can only be added when the dialog is filtered by .NET 4.0 Framework (and not the Client framework).

The key difference between this interface and the one use for the DataService is the WebGet() that has been added to the Operation Contract and it will invoke the GetClientAccessPolicy() method when a GET request matches the template.  The more typical use of this pattern is to respond to more generic request pattern, however it is ideal for handling the Silverlight request.

http://localhost:1234/clientaccesspolicy.xml

The code to handle the request is also very simple:

using System.IO;
using System.ServiceModel.Web;
using System.Reflection;

namespace ConsoleApplicationWCF
{
    public class WebServer : IWebServer
    {
        public const string AssemblyRootPath = "ConsoleApplicationWCF.";

        public Stream GetClientAccessPolicy()
        {
            WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
            return Assembly.GetExecutingAssembly().
               GetManifestResourceStream(AssemblyRootPath + "ClientAccessPolicy.xml");
        }
    }
}

 

The AssemblyRootPath is the namespace for the application.  This should be ConsoleApplicationWCF but can be confirmed by looking at the Default Namespace in the Projects Properties.

Add the following XML as a ClientAccessPolicy.xml file to the project and make sure that the Build Action for the file is set to ‘Embedded Resource’.  When the project is built the xml file will be built into the binary file.

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

 

When the method is invoked the file data is returned to the caller.

The final part of the process is to create a web server endpoint to handle this contracted request.

   <behaviors>
    <endpointBehaviors>
      <behavior name="WebServerEndpointBehavior">
        <webHttp />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior name="WebServerBehavior">
        <serviceMetadata httpGetEnabled="false" />
        <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="true" />
      </behavior>
        ...
    </serviceBehaviors>
   </behaviors>

 

Notice that there is an endpointBehaviour and a serviceBehaviour. 

These two behaviours are used in the definition of the WebServer service:

    <service behaviorConfiguration="WebServerBehavior" name="WebServer">
      <endpoint address="" behaviorConfiguration="WebServerEndpointBehavior"
        binding="webHttpBinding" contract="IWebServer">
        <identity>
          <dns value="localhost" />
        </identity>
      </endpoint>
      <host>
        <baseAddresses>
          <add baseAddress="http://localhost:1234/" />
        </baseAddresses>
      </host>
    </service>

 

Notice that the <service> behaviourConfiguration uses the WebServerBehaviour and the <endpoint> behaviourConfiguration uses the WebServerEndpointBehaviour.  I know that this looks simple but it’s driven me mad while configuring WCF previously – the trick I think is to make sure the names are really reflecting the configuration!

The binding for the WebServer is ‘webHttpBinding’ which will respond to the HTTP GET method that Silverlight makes (and notice that the GetClientAccessPolicy() outgoing content type is ‘text/html’

Here is the full service configuration for both the WebService and the DataService:

<?xml version="1.0"?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="WebServerEndpointBehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="WebServerBehavior">
          <serviceMetadata httpGetEnabled="false"/>
          <serviceDebug httpHelpPageEnabled="false" includeExceptionDetailInFaults="true"/>
        </behavior>
        <behavior name="DataServiceBehavior">
          <serviceMetadata httpGetEnabled="true"/>
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="WebServerBehavior" name="ConsoleApplicationWCF.WebServer">
        <endpoint address="" behaviorConfiguration="WebServerEndpointBehavior" 
             binding="webHttpBinding" contract="ConsoleApplicationWCF.IWebServer">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/"/>
          </baseAddresses>
        </host>
      </service>
      <service behaviorConfiguration="DataServiceBehavior" name="ConsoleApplicationWCF.DataService">
        <endpoint address="" binding="basicHttpBinding" contract="ConsoleApplicationWCF.IDataService">
          <identity>
            <dns value="localhost"/>
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/DataService"/>
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
  </startup>
</configuration>

And now when the Silverlight application runs and the button is pressed it will request the client access policy file, validate it and then assuming its all OK will fetch the date and time. Awesome!

image

Written by metadevblog

March 28, 2011 at 10:58 pm

Posted in Silverlight, WCF

Tagged with ,

WCF–Testing the DataService

leave a comment »

The quickest way to test that the Data Service is working is to create a simple Windows Forms based application as this will be able to connect without encountering any of the cross domain issues that a Silverlight application will hit.

Once this test has completed then the WCF service will be changed so that a Silverlight application can be created.

Create a new Windows Forms based application in VS2010.  Its best to develop the application in a separate instance of VS2010 rather than adding new project to the solution because then the DataService can be left running while the client is being developed.

Ensure that the ConsoleApplicationWCF is running and the DataService console window is displayed.

Add a button and a label to the Form1 that will have been created automatically by VS.

In the Project Solution right click on References and select Add Service Reference.  Enter the address of the DataService (e.g. http://localhost:1234/DataService).  Click the Advanced button and tick the ‘Generate asynchronous operations’ checkbox.  Asynchronous operations are slightly more tricky to use but is the only option when using Silverlight so it may as well be implemented now.

Once the service reference has been created (and you can see that the process creates quite a bit of code and support files if you ‘show all files’ in the project Solution explorer) it can be used with relative ease.

One of the really great things about WCF is how much work the Microsoft developers have put into hiding the complexity of what is a very complex process.

The code pretty much writes itself, you only have to remember a couple of names in order to get it working.

The starting point when using the service reference is to create a reference to the service code that has been used, the will be called DataServiceClient.

DataServiceClient dataService = null;

 

Adding this will report an error.  Right clicking on DataServiceClient and selecting Resolve will add the correct using statement to the class (it should be  “using WindowsFormsWCF.DataService”).

Using the event driven asynchronous access pattern that is exposed via the code that has been generated during the creation of the service reference exposes the functionality of WCF.  VS2010 IntelliSense will virtually fill out the code to access the service.  So the button click code should look like this:

        private void button1_Click(object sender, EventArgs e)
        {
            dataService.GetDateTimeCompleted += new EventHandler
                    <GetDateTimeCompletedEventArgs>(dataService_GetDateTimeCompleted);
            dataService.GetDateTimeAsync();
        }


The GetDateTimeCompleted delegate simply needs an appropriate event handler to be added and IntelliSense will event generate the name of the handler “dataService_GetDateTimeCompleted” all that needs to be done is add it to the code.

        void dataService_GetDateTimeCompleted(object sender, DataService.GetDateTimeCompletedEventArgs e)
        {
            try
            {
                XElement xResult = (XElement)e.Result;

                string date = xResult.Element("Date").Value;
                string time = xResult.Element("Time").Value;

                label1.Text = string.Format("The date is: {0}\nThe time is: {1}", date, time);

            }
            catch (Exception ex)
            {
                label1.Text = string.Format("Error occurred: {0}", ex.Message);
            }
        }


The only bit of work that has be hand cranked is to remember that the event handler will have the following parameters:

(object sender, DataService.GetDateTimeCompletedEventArgs e)

The e.Result will be returning an XElement, as this was defined in the original service.  I’m simply grabbing the Date and Time elements from the XML, formatting them and showing the result in the label.

image

The code for the application is:

using System;
using System.Windows.Forms;
using WindowsFormsWCF.DataService;
using System.Xml.Linq;

namespace WindowsFormsWCF
{
    public partial class Form1 : Form
    {
        DataServiceClient dataService = null;

        public Form1()
        {
            InitializeComponent();

            dataService = new DataServiceClient();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            dataService.GetDateTimeCompleted += new EventHandler<GetDateTimeCompletedEventArgs>(dataService_GetDateTimeCompleted);
            dataService.GetDateTimeAsync();
        }

        void dataService_GetDateTimeCompleted(object sender, DataService.GetDateTimeCompletedEventArgs e)
        {
            try
            {
                XElement xResult = (XElement)e.Result;

                string date = xResult.Element("Date").Value;
                string time = xResult.Element("Time").Value;

                label1.Text = string.Format("The date is: {0}\nThe time is: {1}", date, time);

            }
            catch (Exception ex)
            {
                label1.Text = string.Format("Error occurred: {0}", ex.Message);
            }
        }
    }
}

 

Transforming this code to Silverlight is pretty simple.  Create a new Silverlight Application project in VS2010 (remove the checkmark for hosting in a new web site).

In the MainPage.xaml add a Button and a TextBox.  Create the Service Reference and then paste in the following code:

using System;
using System.Windows;
using System.Windows.Controls;
using SilverlightApplicationWCF.DataService;
using System.Xml.Linq;

namespace SilverlightApplicationWCF
{
    public partial class MainPage : UserControl
    {
        DataServiceClient dataService = null;

        public MainPage()
        {
            InitializeComponent();

            dataService = new DataServiceClient();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                dataService.GetDateTimeCompleted += new EventHandler<GetDateTimeCompletedEventArgs>(dataService_GetDateTimeCompleted);
                dataService.GetDateTimeAsync();
            }
            catch (Exception ex)
            {
                textBlock1.Text = string.Format("Error occurred: {0}", ex.Message);
            }
        }

        void dataService_GetDateTimeCompleted(object sender, DataService.GetDateTimeCompletedEventArgs e)
        {
            try
            {
                XElement xResult = (XElement)e.Result;

                string date = xResult.Element("Date").Value;
                string time = xResult.Element("Time").Value;

                textBlock1.Text = string.Format("The date is: {0}\nThe time is: {1}", date, time);

            }
            catch (Exception ex)
            {
                textBlock1.Text = string.Format("Error occurred: {0}", ex.Message);
            }
        }
    }
}


Apart from a few name differences its the same code!

Run the application and you will get a warning about debugging issues when using web services (you can see what’s coming soon…).  Ignore the warning and continue to run the application and while the Silverlight form will display, as soon as you click the button an cross-domain error will be thrown:

image

The next post will show how this is solved quite elegantly.

Written by metadevblog

March 24, 2011 at 11:07 pm

Posted in WCF

Tagged with ,

WCF–Service Behaviours, Bindings and Contracts

leave a comment »

WCF is now a very mature technology and one that I have used a great deal over the last few years, in fact it has been core to most of my recent work both professionally and with personal development projects.

I can’t however be the only one to have struggled with getting the triumvirate of behaviours, bindings and contracts to work together when creating a web service without at least tearing some of my hair out.

I don’t know if there is something different in WCF 4.0 or its just ‘clicked’ for me finally but I managed to create two web services in a hurry last night and get them working by actually understanding the XML.  So while it is still fresh in my mind I’m going to write it down…

One of the pitfalls with using WCF is the number of different parts that need to be created before it can be tested end to end.  There are also some ‘gotchas’ that need to be avoided along the way.

Exposing data via WCF requires a data service.  I typically use XML for both sending and receiving data to/from services, so before any description of setting up WCF can be given it is first of all necessary to create a data service that will provide some information.

The data service is a pre-requisite because WCF binds to a service interface that will be exposed at the service endpoint (an example HTTP service endpoint is http://localhost:1234/DataService which will be described below).

In order to expose the service endpoint the service provider is hosted within a ServiceHost object.  ServiceHost is a core windows technology that is also a core part of IIS.  ServiceHost can be hosted within any persistent application, even a console application, but it provides excellent functionality when used with a Windows Service.

I have used Visual Studio 2010 and .NET 4.0, all the code is in c#.

The first part of this article will cover the creation of the data service provider.  The configuration of the service will follow and then I will create a simple application to access the service.

The next part of this article to follow will add another service so that Silverlight can be used to access the data service.

ConsoleApplicationWCF.sin


Create a new console application in VS2010; make sure you call it ConsoleApplicationWCF.

IDataService.cs


Add a new class called IDataService.cs and then paste this code in (you will probably get some errors reported which can be cleared by adding System.XML.Linq.dll and System.ServiceModel.dll to the projects references)

using System.ServiceModel;
using System.Xml.Linq;

namespace ConsoleApplicationWCF
{
    [ServiceContract]
    public interface IDataService
    {
        [OperationContract]
        XElement GetDateTime();
    }
}

This will create the DataService interface which will be referenced in the WCF service endpoint contract as ConsoleApplicationWCF.IDataService.  Note that it is necessary to include the namespace when identifying the endpoint in the definition.

The [ServiceContract] and [OperationsContract] are code decorations that are used during compilation to build the service interface.  The [ServiceContract] decoration identified IDataService as the contract that will be used in the service definition.  The [OperationContract] will allow the GetDataTime() method to be accessed via the service.

DataService.cs

Add a new class called DataService.cs and then paste in this code to implement the interface.  Notice that the service is returning a Linq XElement.

using System;
using System.Xml.Linq;

namespace ConsoleApplicationWCF
{
    public class DataService : IDataService
    {
        public XElement GetDateTime()
        {
            XElement result = new XElement("Data");
            result.Add(new XElement("Date", DateTime.Now.Date.ToString()));
            result.Add(new XElement("Time", DateTime.Now.TimeOfDay.ToString()));

            return result;
        }
    }
}

Program.cs

Now replace the Program.cs stub code that was generated when the project was created with this code:

using System; 
using System.ServiceModel; 
namespace ConsoleApplicationWCF 
{ 
    class Program 
    { 
        private static ServiceHost dataService;

        static void Main(string[] args) 
        { 
            try 
            { 
                dataService = new ServiceHost(typeof(DataService)); 
                dataService.Open(); 
            } 
            catch (Exception e) 
            { 
                Console.WriteLine("Unable to start DataService:" + e.ToString()); 
            }

            Console.WriteLine("Service started at http://localhost:1234/DataService"); 
            Console.ReadLine();
        } 
    } 
} 

The WCF DataService is hosted directly in the Console by ServiceHost. When implementing this within a Windows Service the code can be pretty much lifted verbatim and put into the OnStart event which will then start the WCF DataService when the Windows Service starts.

 

App.config

The key to getting WCF to work is a correct service configuration file.  Add an empty App.config file to the project and then paste the following XML into the file.  This configuration is about as simple as can be defined for a basic HTTP data service.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="DataServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <services>
      <service behaviorConfiguration="DataServiceBehavior" name="ConsoleApplicationWCF.DataService">
        <endpoint address="" binding="basicHttpBinding" contract="ConsoleApplicationWCF.IDataService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/DataService" />
          </baseAddresses>
        </host>
      </service>
    </services>
  </system.serviceModel>
</configuration>


The actual WCF definition is within the <system.serviceModel> element but it is being wrapped within a <configuration> element that is used by App.Config which the console application can access directly as part of its implementation structure.

The <system.serviceModel> element contains two main regions which allow for multiple <behaviours> and <services> to be defined.  The <behaviour> define how a <service> will function.

The service <behaviour> for a WCF data service requires that httpGet is enabled.  I also enable includeExceptionDetailInFaults on the basis that you can never have too much information about what has gone wrong and you can always switch it off later.

Creating the <service> itself is usually where it all goes wrong as there are so many parts to it; any one of which will cause an error (or worse no service).

The <service> element contains one or more <endpoint> elements and a <host> element.

<service>   
  <endpoint />   
  <host /> 
</service>

Note that a service can have multiple endpoint definitions.  This is important as the endpoints provide different data depending on their configuration.

The service behaviour uses the behaviourConfiguration to map a behaviour to the service using the behaviour attribute name.

<behavior name="DataServiceBehavior"> 
<service behaviorConfiguration="DataServiceBehavior"  …

The name of the service should be the same as the name in the interface and should include the namespace.

<service behaviorConfiguration="DataServiceBehavior" name="ConsoleApplicationWCF.DataService">

The service exposes two endpoints one is used to access the data, the other is used get the metadata that describes the service.  This second service is vital as it simplifies the whole process of making use of the service by auto-generating a while bunch of plumbing files that hide away most of the complexity of WCF.

The first <endpoint> is for the data service.  It is exposing the service as HTTP and it is using the IDataService contract that has been defined. The namespace should be used in the definition of the contract.

<endpoint address="" binding="basicHttpBinding" contract="ConsoleApplicationWCF.IDataService">

The dns specifies “localhost”.  This is perfectly valid but it should not be confused with using the name of your machine.  You should change both the dns and the actual endpoint if you want to use a machine name.

The second endpoint is for getting the service metadata that will be used to generate the WCF service support files in a client application.  The service metadata can be accessed by invoking the service endpoint in a browser along with the ?wsdl parameter (the parameter triggers access to the MEX endpoint).  Eg

http://localhost:1234/DataService?wsdl

Finally the address of the service can be defined.  I tend to use the same name as the service contract for my services and also leave them open ended – ie no terminating /

That’s about it for this posting.  The code should compile and run and will show the following console:

image

Written by metadevblog

March 23, 2011 at 9:22 am

Posted in WCF

Tagged with ,