WCF Services – Configuring and Debugging – Part I

What are Windows Communication Foundation Services?

WCF Services were introduced in .NET 3.0. They are Microsoft’s effort to consolidate their technology for remote procedure invocation and for creating Service Oriented Architectures. If you are using Visual Studio, in theory it is very easy to create and consume these services, and for simple controlled scenarios, that is truly the case.

However for anyone who has tried to use this technology in more realistic scenarios as a basis for building a real Service Oriented Architecture might have ealized, there are many subtleties involved, and configuring the ServiceModel XML in web.config or app.config can be a tedious and time consuming process.

I recently spend a lot of time buried inside this technology and have a few tips and simple explanations that might save you some time and sanity. In this post I want to expose you to the default configurations you get while choosing different kinds of WCF Services in Visual Studio. I’ll stick to the basics and build on that for future posts.

So here goes…

Once you have a project (either a ASP.NET application or a Service Application or one of many other project types that come packaged with Visual Studio), you can add a service to it by going to the “Add”->”New Item” menu and choosing one of the following:

  1. WCF Service
  2. Ajax Enabled WCF Service

To follow along with this post, go ahead and create one service of each type.

So what is the difference between a “WCF Service” and an “Ajax Enabled WCF Service”?

In plain English, the “WCF Service” has settings on it that make it suitable for consumption by desktop applications. The “Ajax Enabled WCF Service” has settings on it that make it suitable for consumption by web applications. These settings are in web.config, and in the way the classes that define the service are setup.

1. WCF Service

Let’s say I create a “WCF Service”, called WCFService, I will end up with a configuration in my web.config file that looks something like this. I called by project WCFConfigAndDebugging and so Visual Studio automatically tags that to some of my configuration elements.

<system.serviceModel>
	<service behaviorConfiguration="WCFConfigAndDebugging.WCFServiceBehavior"
                                                  name="WCFConfigAndDebugging.WCFService">
		<endpoint address="" binding="wsHttpBinding" contract="WCFConfigAndDebugging.IWCFService">
			<identity>
				<dns value="localhost" />
			</identity>
		</endpoint>
		<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
	</service>
	<behaviors>
		<serviceBehaviors>
			<behavior name="WCFConfigAndDebugging.WCFServiceBehavior">
				<serviceMetadata httpGetEnabled="true" />
				<serviceDebug includeExceptionDetailInFaults="false" />
			<behavior>
		</serviceBehavior>
	</behavior>
</system.serviceModel>

Firstly, assuming the service was created right under the project (not in a sub folder), and that the project was published to the server myserver.com, the URL for the service will be http://myserver.com/WCFService.svc

The important parts to notice are:

The service has 2 endpoints

  • The <endpoint address=”” binding=”wsHttpBinding” contract=”WCFConfigAndDebugging.IWCFService”> specifies that the default end point (default because of the address =””) for this service is the one represented by the interface WCFConfigAndDebugging.IWCFService. That interface is generated automatically for you when you create the service. The binding=”wsHttpBinding” means that XML should be used to send requests to this service, and that the response will be serialized into XML. What this all means is that when the URL http://myserver.com/WCFService.svc is hit with an HTTP GET request, any of the methods on the WCFConfigAndDebugging.IWCFService interface can be invoked, and request should and response will be serialized to XML.
  • The <endpoint address=”mex” binding=”mexHttpBinding” contract=”IMetadataExchange” /> specifies that there is another URL http://myserver.com/WCFService.svc/mex which exposes the methods on the IMetadataExchange interface. That interface is defined in the .NET framework.
  • The service itself has 2 pieces of additional “behavior” specified
    • The <serviceMetadata httpGetEnabled=”true” /> specifies that your service can be queried for meta information (basically what are the methods on it, what inputs they take and what outputs they give) using HTTP GET requests. Since you chose “WCF Service”, Visual Studio (i.e. some Program Manager at Microsoft)assumed that its okay to expose that information. That actually makes sense because in this case the service will be most probably be consumed by WCF aware Windows applications.
    • The <serviceDebug includeExceptionDetailInFaults=”false” /> specifies that if there is an exception thrown during the execution of a service request, the details (call stack, inner exception etc) will not be sent as a part of the response to the invoker of the service. Visual Studio thinks that the information might compromise your security and hence sets this to false.

Service “behavior” is specified separately and then applied to a service, so that it can potentially be reused across many services.

2. Ajax Enabled WCF Service

Now let’s say I create an “Ajax Enabled WCF Service”, called AjaxEnabledWCFService, I will end up with a configuration that looks something like this

<system.serviceModel>
	<service name="WCFConfigAndDebugging.AjaxEnabledWebService">
		<endpoint 	address=""
                    		behaviorConfiguration="WCFConfigAndDebugging.AjaxEnabledWebServiceAspNetAjaxBehavior"
                    		binding="webHttpBinding" contract="WCFConfigAndDebugging.AjaxEnabledWebService" />
	</service>
	<behaviors>
		<endpointBehaviors>
			<behavior name="WCFConfigAndDebugging.AjaxEnabledWebServiceAspNetAjaxBehavior">
			<enableWebScript />
			</behavior>
		</endpointBehaviors>
	</behaviors>
</system.serviceModel>

Again, the URL for the service will be something like this http://myserver.com/AjaxEnabledWCFService.svc

The important parts to notice here are:

  • The service has only one endpoint. The <endpoint address=”” behaviorConfiguration=”WCFConfigAndDebugging.AjaxEnabledWebServiceAspNetAjaxBehavior” binding=”webHttpBinding” contract=”WCFConfigAndDebugging.AjaxEnabledWebService” /> specifies that any method on the class WCFConfigAndDebugging.AjaxEnabledWebService can be invoked using the URL http://myserver.com/AjaxEnabledWCFService.svc. The binding=”webHttpBinding” specifies that the communication (request-response) will not be using XML. It will be using the format specified in the endpoint’s behavior which is specified separately.
  • The endpoint behavior has only one configuration specified. The <enableWebScript /> specifies that the request and response should be using JSON, which make sense since Ajax requests are usually made using JSON.

As you might have noticed, metadata about the service is not exposed by default because this service will most probably be exposed on the internet, and it makes sense to only allow clients that already know about the service and its definition to be able to invoke it. That’s why there is no “mex” end point exposed by the service.

ASP.NET Compatibility

As mentioned before, “Ajax Enabled WCF Services” are meant to be consumed from web clients. So when a new one is created from Visual Studio, the class representing the service is automatically decorated with an attribute to alllow that. If you created the service above, in your AjaxEnabledWCFService.svc file you should see this

[ServiceContract(Namespace = "")]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AjaxEnabledWCFService
{
	…
}

The attribute

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 

tells WCF that this service can be accessed from web applications. Without it, web access to the service would be denied.

We’re done with Part I

Once these services above have been created they can be consumed by desktop or web applications. However, to be able to correctly consume them, the request and response formats the client uses/expects (XML, JSON etc) must match up with the configuration specified (endpoints exposed) for the service.

In the next post, we’ll see how to use our browsers and a tool called wcftestclient.exe to access information about these services.

Advertisements

About floatingfrisbee

A programmer/blogger from New York City
This entry was posted in web services and tagged , . Bookmark the permalink.