This problem has been solved and answered many different ways but none of the answers seem to propose a complete basic or step by step solution.  This article is my attempt to consolidate the answer into one concise how to article.

Executive Summary

For those of you that want the answers quickly, here are the steps necessary to properly use WebGet methods in a WCF Service:

  1. Use the WebGet attribute and specify a UriTemplate.
  2. Use the webBinding binding type in your web.config.
  3. Create an endpoint behavior that specifies webHttp in your web.config.
  4. Reference the endpoint behavior in the service endpoint configuration section.
  5. Set the binding in the service endpoint configuration to webHttpBinding (or to the name of the binding configuration that specifies webHttpBinding).

How-To / Step by Step

In this section we will go through the process of creating a simple service with Visual Studio 2010 that performs a simple WebGet operation.

Create a new WCF Service Application project.

image

I am going to leave the default Service1 class and interface names intact for simplicity.

Open the IService1.cs code file and change it so that it looks like this:

Note the WebGet attribute in the interface definition.  Now we are going to modify the Service1.cs file to implement the AddNumbers method.

This implements the method.

Compile the project and make sure it builds. Next we are going to update the web.config file so this actually works.

In Visual Studio click Tools | WCF Service Configuration Editor, Load the web.config file for this new project.

image

You will see the WCF Config Editor.

Now we are going to create a Service Endpoint and an Endpoint Behavior.

Click the Services configuration node and click Create a New Service.

Click Browse to find the service type.  You are going to navigate to the DLL that implements your WCF service (hint, it should be in your /bin folder).

image

After clicking Open you will be allowed to choose the class that implements your service.  Click it and then click Open.

image

After clicking Open you will click Next.  This will bring you to the service contract screen.  This screen is asking you what the interface is that describes your service.  Typically this will be automatically detected and filled out for you.

image

Click Next.

image

Choose HTTP and click Next.

image

Choose Basic Web Services interoperability and click Next.

For the Endpoint Address enter / and click Next then on the summary page click Finish.

image

You will now have a service configured in your Web.config file.

image

Now we will create an endpoint behavior.  Expand Advanced, Right Click on Endpoint Behaviors and choose New Endpoint Behavior.

image

Click Add, Choose webHttp and click Add.

image

The new behavior configuration screen will now look like this:

image

Change the Binding to webHttpBinding and select the NewBehavior0 behavior configuration.

image

Click Save and exit from the WCF Service Configuration tool.

Now you should be able to start your WCP project and navigate to the web method in your browser and see a result like below.

image

Note that the URL contains your .svc file and then the UriTemplate property of the WebGet attribute kicks in. 

Source code for this project: WebGetTest.zip

Business Problem

Remote warehouses are not directly connected to the central office and thus are not connected to the ERP System (Microsoft Dynamics Ax 2009).  Employees at remote warehouses need to perform inventory transactions on iTouch devices and some of these transactions require a label to be printed on a Zebra label printer.  Label printing typically involves a centralized print server that formats and streams the print job to a Windows Print Queue.  Remote printing using a Microsoft Print Queue is not feasible across the internet.

Solution

The solution to this problem was to build  a simple Windows Service which self hosts a WCF service.  The Windows Service has the ability to function as both a server and a client.  The service can poll other services for print jobs, if the print job is local the job is sent to a local label printer, if the job is remote it is queued for a remote server to poll (via WCF Services).  Print jobs are archived which allows a user to load the Status Monitor application and reprint a label.

http://alphafn.com/oldpics/PrintConfig

Users can reprint labels using the above status screen.

http://alphafn.com/oldpics/PrintConfig2

User’s can configure the print server, start and stop the service, and update the application using the configuration screen.

This software is written in .NET 4.0 using WPF/XAML as the UI.  The application implements the Model-View-ViewModel MVVM pattern.  The Windows Service is written in .NET 4.0 and self hosts a WCF Service.  Remote printing is implemented using WCF with client/server X.509 certificates for security.

Business Problem

Large companies have lots of facilities which need spare part inventory on hand.  Facility operators may not reorder parts in a timely fashion which can lead to a local shortage of equipment.  Some facilities may hoard equipment creating a local surplus of equipment.  Both extremes are costly to a company.

Solution

Provide a simple to use touch screen computer that detects when a part is leaving or entering the spare parts room.  Upon detection of the part the touch screen computer displays a ‘tag’ with information about the part.  The facility user can touch the tag on the screen and note the use of the part.  When parts come in for replenishment the facility user can notate the put away location of the part.  When are part is used inventory levels at MDSi are updated.  If the minimum stocking level is reached a reorder is automatically generated and shipped to the facility to keep the stocking level true.

Components

RFID Client (Touch screen workstation)
This is the device with which the facility users interact.

image

The client is built with Microsoft .NET Framework 4.0 and uses Windows Presentation Foundation (WPF) to present the UX.  The client leverages the Model-View-ViewModel (MVVM) architectural pattern and is written in C#.  Communication to the home office is provided via WCF services.

image

RFID Tags are read via a Motorola XR-450 tag reader.  This reader was selected because it has a built in Windows CE operating system that allows us to write Mobile Embedded .NET applications to interact with the reader and with our WCF Services.  The RFID Client Workstation has a Windows Service written in C# and .NET 4.0 which continually polls the XR-450 reader for new tags.  The service exposes a .NET Remoting service which is consumed locally by the client UI.  Multicast events are thrown and the client system can respond to new tags accordingly.

RFID WCF Services
All RFID Clients communicate to a set of centralized web servers in an NLB farm.  The WCF Services provide a data exchange layer which provides caching by leveraging the AppFabric Cache feature of Windows Server 2008 R2.  Data is stored in a SQL 2008 R2 Cluster and the data is organized through Microsoft Dynamics AX 2009.  X++ and Business Connector code was created to interface through the ERP system and pass through all of the business rules configured in the Dyanmics Ax system.  In addition to using the .NET Business Connector and custom Dynamics Ax projects to manage the data, ADO.NET, Linq and C# is used in the creation of these services.

RFID Management Display
A Network Operation Center (NOC) application was created to provide real-time node (RFID Touch Screen Client) availability data.  This data is organized on a map and allows an operator to drill in to a workstation and remotely manage the system.

image

RFID Warehouse Printing
Tools were created to interface with the Microsoft Dynamics Ax 2009 ERP system which allow a warehouse employee to print RFID labels for items being shipped out for replenishment.  This system interfaces with the Zebra RZ 400 RFID Printer.  This application was created using WPF, WCF, MVVM.

image

RFID On-Site Inventory and Auditing Tool
This application allows a warehouse specialist to audit a sparing facility.  This application is written using WPF and .NET 4.0.  The application consumes the same WCF services provided for the RFID Client to connect to the ERP system.  The application allows a specialist to print labels via a wireless Zebra RP4T RFID Label printer.  Using this application a project coordinator can determine what inventory is needed on site and what can be returned for general usage to the Distribution Center (DC).  This allows for a quick and efficient auditing process.  The warehouse specialist does not need to know anything about the product, just scan the serial number and the application tells the specialist the disposition of the part based on the Min/Max settings in the ERP system.

image

RFID Node Creation Tool
The Node Creation Tool allows a support engineer to provision a remote RFID Touch Screen Client from a central location.  A support engineer can provision all of the standard configuration settings for Development, Test, and Production from the single tool.  This application was created with WPF, C#, WCF, MVVM.

image

RFID Online Spares Management Web Application
A Silverlight application was created to provide scaled down functionality for locations that do not have the RFID Touch Screen client installed.  Some locations need the ability to consume, count and audit their inventory without an RFID client.  In this case a laser barcode scanner is used to scan the RFID barcode.  This application was written in Silverlight 4.0, uses WCF Services, and employs the MVVM architectural pattern.

image

So I went in and took 5 of the 6 new beta exams (the 6th one was the TS Exam for Web, that one was full and could not take it for free) and I am happy to say I passed 5 of the 5 I took.  I just need to take the Web TS and I should add Web Developer 4 and Enterprise Developer 4 to the MCPD.

Now my Microsoft Certifications look like this:

519
Pro: Designing and Developing Web Applications Using Microsoft .NET Framework 4.0
Apr 09, 2010

518
Pro: Designing and Developing Windows Applications Using Microsoft .NET Framework 4.0
Apr 08, 2010

516
TS: Microsoft .NET Framework 4, Accessing Data with ADO.NET
Apr 07, 2010

513
TS: Microsoft .NET Framework 4, Windows Communication Foundation Development
Apr 06, 2010

511
TS: Microsoft .NET Framework 4, Windows Applications Development
Apr 05, 2010

http://alphafn.com/oldpics/MCPD(rgb)_1371http://alphafn.com/oldpics/MCTS(rgb)_1269_1374_1369_1373_514

http://alphafn.com/oldpics/MCSE(rgb)

 

http://alphafn.com/oldpics/MCPI(rgb)

http://alphafn.com/oldpics/MCPSB(rgb)

So as it turns out pretty much all the examples I have read online show no attributes when using the binaryMessageEncoder.

As it turns out, just like text encoding, you can add a readerQuotas element like this:

Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.
Parser Error Message: Unrecognized attribute ‘multipleSiteBindingsEnabled’. Note that attribute names are case-sensitive.
Source Error:

Source File: C:\inetpub\web\services.test.\RFIDServer\web.config    Line: 107


Version Information: Microsoft .NET Framework Version:4.0.21006; ASP.NET Version:4.0.21006.1


Received the above error message when executing a WCF service on a test server.  The WCF service was compiled with .NET  4.0 RC and the test server only had .NET 4.0 Beta 2 installed.  The fix was easy.  Install .NET 4.0 RC full runtime on the test server and it worked.

Update:  Good news!  Microsoft has verified that in the RTM build this bug has been resolved.  Much thanks to Go-Live support for taking this issue on and validating the issue is resolved.

From VS2010 Beta 2 to VS2010 RC we lost the ability to choose the data type ObservableCollection when configuring a service reference in a Silverlight application.  I am going to use this blog post to chronicle my discussion with Microsoft Go-Live support about this functionality change.

This may be a user education issue but the difference is significant and affects all of the production projects we currently have for Visual Studio 2010 Beta 2.

Today we upgraded 3 of our developer machines from Visual Studio 2010 Beta 2 to the Visual Studio 2010 RC.  In beta 2 when adding a Service Reference to a Silverlight 3 application we were given the option to choose a collection type of: System.Collections.ObjectModel.ObservableCollection in the Collection type drop down box.

http://alphafn.com/oldpics/clip_image002

Now in the release candidate we are no longer given the option to choose ObservableCollection.  Instead the dropdown offers ( Custom ), Array, Generic List (and another).  This presents us with several issues.  Existing Beta 2 code can no longer update service references without converting all return types from Array[] or List<> to an ObservableCollection. 

For Silverlight applications this is pretty major as we pass Generic Lists from our WCF service and heavily relied on the ability for the WCF Proxy class to deserialize the list into an ObservableCollection since these are bindable directly to our Silverlight grids.

Please advise.  Is this the way this will work in production or is it possible to patch the RC to provide this functionality once again.

Please feel free to call me tomorrow ( 2/10/2010 ) from 9AM EST to 8PM EST to discuss if you need more information.  It has been a while since I used Visual Studio 2008, but I am pretty sure that VS 2008 also provided the ObservableCollection collection type option when configuring a service reference.

To verify the Beta 2 vs. RC functionality difference I tested this against the same exact WCF service in both B2 and RC.

I started receiving this error after I added some code to my App.xaml.cs file.

image

 

After some searching I found some outdated info.  Basically this is a timing issue.  I inserted this code in my App.xaml.cs file:


So the problem is with line #1.  This line is trying to read from the ServiceReferences.config file that can not be read at that point in the Silverlight application’s lifecycle.  Changing the code like this works:


Hope this helps someone 😉

 

 

 

Full error below:

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET CLR 1.1.4322; .NET4.0C; .NET4.0E; InfoPath.3)

Timestamp: Tue, 8 Dec 2009 18:19:34 UTC

Message: Unhandled Error in Silverlight 3 Application

Code: 4004   
Category: ManagedRuntimeError      
Message: System.InvalidOperationException: Cannot find ‘ServiceReferences.ClientConfig’ in the .xap application package. This file is used to configure client proxies for web services, and allows the application to locate the services it needs. Either include this file in the application package, or modify your code to use a client proxy constructor that specifies the service address and binding explicitly. Please see inner exception for details. —> System.Xml.XmlException: Cannot open ‘ServiceReferences.ClientConfig’. The Uri parameter must be a relative path pointing to content inside the Silverlight application’s XAP package. If you need to load content from an arbitrary Uri, please see the documentation on Loading XML content using WebClient/HttpWebRequest. —> System.ArgumentException: Application object is not initialized.

   at System.Windows.Application.GetResourceStream(Uri uriResource)

   at MS.Internal.JoltHelper.ApplicationResourceStreamResolver.GetApplicationResourceStream(Uri relativeUri)

   at System.Xml.XmlXapResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)

   — End of inner exception stack trace —

   at System.Xml.XmlXapResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)

   at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)

   at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings, XmlParserContext inputContext)

   at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings)

   at System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup()

   — End of inner exception stack trace —

   at System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup()

   at System.ServiceModel.Configuration.ServiceModelSectionGroup.get_Current()

   at System.ServiceModel.Description.ConfigLoader.LookupChannel(String configurationName, String contractName, Boolean wildcard)

   at System.ServiceModel.Description.ConfigLoader.LoadChannelBehaviors(ServiceEndpoint serviceEndpoint, String configurationName)

   at System.ServiceModel.ChannelFactory.ApplyConfiguration(String configurationName)

   at System.ServiceModel.ChannelFactory.InitializeEndpoint(String configurationName, EndpointAddress address)

   at System.ServiceModel.ChannelFactory1..ctor(String endpointConfigurationName, EndpointAddress remoteAddress)

   at System.ServiceModel.ChannelFactory1..ctor(String endpointConfigurationName)

   at System.ServiceModel.EndpointTrait1.CreateSimplexFactory()

   at System.ServiceModel.EndpointTrait1.CreateChannelFactory()

   at System.ServiceModel.ClientBase1.CreateChannelFactoryRef(EndpointTrait1 endpointTrait)

   at System.ServiceModel.ClientBase1.InitializeChannelFactoryRef()

   at System.ServiceModel.ClientBase1..ctor()

   at SFA.SLApplication.Proxies.DataServiceClient..ctor()

   at SFA_SLApplication.App..ctor()    

Line: 56

Char: 13

Code: 0

URI: http://localhost:26140/SFA.SLApplicationSite/

Please note that I am still tweaking this article, I just wanted to publish it quickly because I have had a lot of questions from other developers concerning this very topic.  I will remove this note when the article is complete and I will provide a link to a project that implements this functionality from DB –> L2S –> WCF –> Model –> WPF and Silverlight.

I hope that subject was descriptive enough.  Here is the problem:  You are developing applications using an MVVM and want to use your Model code for WPF applications and Silverlight.  You will quickly find that you need to build your Model and ViewModel in a Silverlight targeted assembly.  Many people actually add the Model and ViewModel class files in the Silverlight project file.  That is a) nasty and b) you can not use your model as your data contract for your WCF service.

The solution I found was very simple.  Create your WCF service and use your Model classes as data contracts.  Now your Model classes will all be decorated with DataContract and DataMember attributes.  These are not compatible with Silverlight so you need a solution for this part of the problem.  In short, you need to conditionally compile out the non-Silverlight compatible attributes (yes it is a bit ugly in code, but it saves you a lot of time and it works!).

Example

So lets walk through a simple application that lists Employee records from a database.  The architecture looks like this:

MVVM-Silverlight

There are a lot of lines there but we will focus on the Silverlight side of things.  The goal is to create one Model class that is shared between the WCF service and the Silverlight application.  This Model class should also be able to be used by WPF applications (and ASP.NET) as well.  I will call the procedure for making the Model work across both architectures Portable Model or pModel. 

Linq / SQL Metal / ADO.NET Entity Framework Objects

Use one of these technologies to get your data from the database into an object.  These objects should NOT (and can not) be passed around through to Silverlight application.  The solution is to use a Portable Model.  In this example I used SQL Metal to generate out a Data Context for my database which has an Employee table.

image

WCF

At my WCF tier I want to perform the following:

  • Query the database and get all the Employees.
  • Convert the DataContext / SQL Metal / Linq objects to a Model object.
  • Send the Model object down the wire to the client.

Traditionally this can be done without issue for WPF applications.  This is because both types of applications are running the full blown CLR.  They can share the same DLL and the WCF proxy will nicely convert the WCF message from the wire into a well typed Model object.

* A note about sending EF or Data Context objects down the wire.  While this will work, technically, if your client uses the full CLR (WPF / ASP.NET), it is highly discouraged.  Take a SQL Metal Data Context object for example.  When you send that type of object down to the client it actually has the ability to talk directly to the database bypassing your WCF layer (and any business logic you should have in your Model or Business Entity code).  Your tiering breaks down at this point your you break many good development practices.

When you throw Silverlight into the mix, the problem becomes a matter of CLR mismatch.  Your traditional Model class that you are sharing between the client and WCF service is built against the full CLR so you can not add the reference to your Silverlight application.  You could use the proxy generated code in the Silverlight application but this really breaks some of MVVM.

Take your ‘Employee’ Model code:


This Model will work for WCF, WPF and ASP.NET but will not work for Silverlight because the agCLR (Silverlight CLR) does not support the DataContract and DataMember attributes.  You could fake it and create a mock attribute in Silverlight but that seems like a poor architecture. 

Enter – Shared Class Files and Conditional Compilation

Visual Studio has had a cool feature for some time that lets you add a ‘Link’ to another source file in a different project.  Both projects will compile the code file and both projects can edit the code.  Physically, only one instance exists.

The Model / CLR dilemma can be solved partially by creating a new Silverlight Class Library project in your solution and adding a Link to the Model class. 

Now your linked class will not yet compile until you tell the compiler to ignore the DataContract and DataMember attributes when building for Silverlight.

You do this by wrapping your attributes in a conditional compilation statement.  This definitely  make the model code look a bit ugly, however the beauty is that now when you build your solution you will end up with a CLR and agCLR compiled version of the assembly.  There are other ways to do this with targeting and platform based builds, however, by doing it this way you can add project references to the Silverlight version of the Model and your project will be much better organized.

 


 

Below you will see the CLR Model (VMR.Model project) and the agCLR Model (VMR.Silverlight.Model project).

image

How do you add one of the Model class code files as a link to the Silverlight Class Library project?

image

Like normal, add an Existing Item to the Silverlight.Model assembly.  Locate the normal Model class on the disk.

image

Click the down arrow next to the Add button and choose Add As Link. 

Now you have one source for both your CLR (WPF) and agCLR (Silverlight) Model code.  By doing this the namespaces are the same and message deserialization is transparent on both platforms.  You can now use your ViewModel (your view model will need to be different for WPF and Silverlight because it will need to reference the platform specific version of the model) in your client code to retrieve the Model data and bind it to the XAML in your WPF or Silverlight application.