Search code examples
c#web-servicesasmxxml-namespaces

What causes a difference between a web service URL and a namespace?


I have an ASP.NET web project that contains a Web Service. When I run the service it brings me to a page showing all the methods that are exposed, using a URL similar to http://api.example.com/game/service.asmx.

In the code for the Web Service there are methods that have the following attributes:

    [WebService(Namespace = "http://webservices.example.com/GameServices/Game1")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Game1 : System.Web.Services.WebService
    {
        // code 
    }

I am a little confused over why the namespace on a class with the webService attribute is different to the path to the web service. Where is that namespace coming from? Is it just made up?


Solution

  • Yes, it is made up.

    That sounds silly, but it's true. The namespace specified there, in your code, will be used on the XML documents that get exchanged as requests and responses for that particular web service. If you put a network trace program on the wire, you'd see those namespace strings used in the messages back and forth. In webservices, Your app need not concern itself with the namespace, usually. The webservices library usually takes care of it for you.

    The namespace is not required to be an HTTP URL, though often people use HTTP URLs. This may be the source of most of the confusion on your part. The IETF Recommendation for XML namespaces suggests that it should be a URI, but that URI need not be an HTTP URI, and in fact it need not have any "network protocol" attached to it.

    The namespace is... a string. It is used as a simple way to qualify information in an XML schema. Think of it like a person's surname. You might know several people named "Chris". You distinguish them by their last names.

    Similarly, the element name "id" may be used in many different XML documents and schema. Applications (and people too) can distinguish between the many different elements that use the qname "id" via their xml namespace.

    Typically, an "information architect" will specify the XML namespace for a document or a webservice as a URI that is hierarchical, unique to the owning organization, and relevant to the meaning of the information in the XML document. (In a small organization the "info architect" is just a developer.) For example http://mycompany.com/services/2013/customer might be a namespace for MyCompany, created in 2013 and pertaining to services, and specifically the customer service.

    In my opinion, there's no real reason to use http:// as the scheme in the URI for an XML namespace, unless you plan to make documentation available at that HTTP URI. You could just as well use urn:mycompany.com/services/2013/customer as the XML namespace. In fact it might be better, because it indicates it's just a name, it's not a locator. (not a web address).

    I normally use a URN, prefixed with urn: as the scheme, to indicate that the namespace is simply a name, a uniquifier.


    EDIT There are rules for the structure of URNs. The basic format is:

    urn:<NID>:<NSS>

    ...where NID is a namespace id, one of a set of special, approved strings and NSS is a namespace-specific string. The list of approved NIDs includes isbn, uuid, ietf, and about 20 others - each one has a specific meaning defined by a distinct IETF RFC.

    Despite the rules about NIDs, many people simply don't bother to conform, and coin their own URNs using their domain name in place of the NID. eg "mycompany.com". (This is what I do, often).

    Then it's your choice how you want to qualify the name further. You can specify "services", to indicate a web service. Some people use the year and month the service was launched in a namespace. This allows you to update the service, and use a different date to distinguish between different elements. An example XML namespace following this naming convention might be:

     urn:mycompany.com:services:2011:04:Game
    

    This is what RFC 2141 calls an "invalid URN" because I didn't use a registered NID. But it serves my purpose. It is a simple step to transform it into a "valid URN" by applying the fdc NID, defined by RFC 4198.

     urn:fdc:mycompany.com:services:2011:04:Game
    

    See how much better that is?

    In the end, most people just establish their own naming convention, something that makes sense for their uses, for internal and partner consumers of the XML data.