ReBuildAll
LenardG's thoughts (mostly) on .NET development

WCF service namespaces (getting rid of tempuri.org)   (Web services)   
Creating WCF servics is really very easy with Visual Studio. All the basic code is generated for you when you add a service to an existing web project or start a new WCF Service Application project. Modifying the "contract" is pretty straightforward too: you just modify the interface for your service, and then the actual implementation. WCF will do everything for you, generate the WSDL, etc. All your clients need to do is download/refresh the WSDL and they are able to use your service. Easy, right?

But when you look at the WSDL that gets generated for your service, you will notice that there are a lot of references to an XML namespace http://tempuri.org. Lets just say if you publish such a service or develope a solution for yor client who will then publish the service with this namespace to their customers - it is just very unprofessional.

Changing the namespace, however, can be more trickier than you thought.

The following article will show you how to deal with namespace changes in WCF. This will work in both WCF 3 / 3.5 and WCF 4. There are some minor changes, for example, with the configuration, but the same things apply.


Quick reference

For those who are impatient to see how this is done, here is a quick reference of the changes we will apply to a simple WCF service to change the namespace. There are four places to change:

- Apply the Namespace property to the ServiceContractAttribute on the service contract interface
- Apply the Namespace property to the ServiceBehaviorAttribute on the class that implements the service
- Apply the Namespace property to the DataContractAttribute on every class that is involved with the service (parameters, return values)
- Change the namespace for the binding, either on the binding class or in the .config file

And now in detail.


The contract namespace

The first step of course is changing the contract namespace. This is pretty easy, and probably something everyone tries first. It is however, not enough. But lets get started anyway.

Assume I have just generated a new WCF service application. I renamed the default Service1 name to RebuildallService, so I have an interface called IRebuildallService and a class called RebuildallService. The .svc file is called RebuildallService.svc. A little too many service words, but I will leave it that way for now :)

The service contract looks like this:

    [ServiceContract]
    public interface IRebuildallService
    {

The ServiceContractAttribute accepts a property called Namespace, and you might have guessed we are going to use that. This will change the namespace on the contract.

So the code now looks lke this:

    [ServiceContract ( Namespace = "http://schemas.umbraworks.net/rebuildall" )]
    public interface IRebuildallService
    {

If I compile and check the WSDL, I will get certain parts with the tempuri.org namespace and others parts with my new namespace. In practice, the wsdl:definitions XML elements will be in the new namespace, but all data and other parts of the WSDL will stil exist in tempuri.org.

A note on namespaces: namespaces ARE NOT URLS!. They might look like one, like in my examples, but there is no such subdomain as schemas actually in existence. Namespaces follow the URI format, but are not actual addresses. They can be used to identify schemas, because usually a company owns a domain name. Thus using that as the schema namespace creates something unique. And that is exactly what namespaces should be: unique.


The service namespace

So, what else do we need to change? The next step is of course the service implementation itself. Currently, it looks like this:

    public class RebuildallService : IRebuildallService
    {

What we want to do is apply the ServiceBehaviorAttribute, which also has a Namespace property.

    [ServiceBehavior(Namespace = "http://schemas.umbraworks.net/rebuildall")]
    public class RebuildallService : IRebuildallService
    {

Looking at the WSDL after this change you will notice that a big part is now in the desired namespace and there are two things left in the tempuri.org namespace: the data types we use and the wsdl:binding element.


The data types

Lets change the namespace for the data types, since it is a rather straightforward change. Currently the example service (the default implementation that Visual Studio provides) contains the following definition for a data type:

    [DataContract]
    public class CompositeType
    {

You might have guessed, we will add the Namespace attribute to the DataContractAttribute.

    [DataContract(Namespace = "http://schemas.umbraworks.net/rebuildall")]
    public class CompositeType
    {

This will change our data types to exist in our new namespace.

If your data is more complex and you have several classes, be sure to apply the Namespace property along with the DataContract attribute to every one of them. Do this also for your enums, otherwise they will exist in the tempuri.org namespace!


The binding

The final element is changing the binding namespace. If you use code-only WCF, you would specify this in the constructor of the Binding class, but since most of the time you will use config files to specify the binding, I will show how to proceed in this latter case.

In WCF4 you have default bindings, so your web.config file will be pretty empty. In WCF3/3.5 the config file will contain the binding by default, so there you can change it more easily.

Anyhow, what you need to do is add the bindingNamespace element to the endpoint element of the service element. Like so:

    <services>
      <service name="WcfNamespaces.RebuildallService">
        <endpoint address="RebuildallService.svc" bindingNamespace="http://schemas.umbraworks.net/rebuildall"
                  binding="basicHttpBinding" contract="WcfNamespaces.IRebuildallService" />
      </service>
    </services>

For WCF4, I would need to add this entire section into my config file. For WCF3/3.5 only the new attribute needs to be added. The WcfNamespaces, in case you wonder, is the .NET namespace my test project was in.

And with this final change, the WSDL will not be in our own custom namespace, and http://tempuri.org is gone for good :)

Some thoughts about namespaces

In the example above, I placed all services, descriptions, bindings and data types in the same namespace. This is of course not needed, you can specify different namespaces for everything, and WCF will handle this. The WSDL will be more fragmented: WCF generates a separate document for different namespaced entities. But there is nothing technically preventing you from doing this.

 

Comments

Re: WCF service namespaces (getting rid of tempuri.org)
Thank you
Andrew Stone Re: WCF service namespaces (getting rid of tempuri.org)
Thanks for posting this. It goes a long way helping unwind the WCF insanity. :)
Robert Re: WCF service namespaces (getting rid of tempuri.org)
Worked like a Charm, thank you!.
sandeep sharma Re: WCF service namespaces (getting rid of tempuri.org)
Hi lenardg ,
I apply the same modification in all places but my service raising an exception thats see below
project Namespace: wcfService1
Interfacce : IRebuildallService
Class : RebuildallService

when i run the my wcfservice it rais this error
if i add the service reference and discover the URI then also not service is listed.please help me on this

Well my service name was service1 earlier and i renamed it after that hope this will help to u to find the solution easily.

Server Error in '/' Application.
--------------------------------------------------------------------------------

The type 'WcfService1.Service1', provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: The type 'WcfService1.Service1', provided as the Service attribute value in the ServiceHost directive, or provided in the configuration element system.serviceModel/serviceHostingEnvironment/serviceActivations could not be found.

Steve Re: WCF service namespaces (getting rid of tempuri.org)
To avoid having to put the namespace information on every single DataContract, you can optionally put an overall ContractNamespace on the whole class:

[assembly:ContractNamespace("http://myservice.com/", ClrNamespace = "MyService")]

Look it up to find more examples.