application integration - How to pass enumerated values to a web service


Translate

My dilemma is, basically, how to share an enumeration between two applications.

The users upload documents through a front-end application that is on the web. This application calls a web service of the back-end application and passes the document to it. The back-end app saves the document and inserts a row in the Document table.

The document type (7 possible document types: Invoice, Contract etc.) is passed as a parameter to the web service's UploadDocument method. The question is, what should the type (and possible values) of this parameter be?

Since you need to hardcode these values in both applications, I think it is O.K. to use a descriptive string (Invoice, Contract, WorkOrder, SignedWorkOrder).

Is it maybe a better approach to create a DocumentTypes enumeration in the first application, and to reproduce it also in the second application, and then pass the corresponding integer value to the web service between them?


Toutes les réponses
  • Translate

    I can only speak about .net, but if you have an ASP.net Webservice, you should be able to add an enumeration directly to it.

    When you then use the "Add Web Reference" in your Client Application, the resulting Class should include that enum

    But this is from the top of my head, i'm pretty sure i've done it in the past, but I can't say for sure.


  • Translate

    I'd suggest against passing an integer between them, simply for purposes of readability and debugging. Say you're going through your logs and you see a bunch of 500 errors for DocumentType=4. Now you've got to go look up which DocumentType is 4. Or if one of the applications refers to a number that doesn't exist in the other, perhaps due to mismatched versions.

    It's a bit more code, and it rubs the static typing part of the brain a bit raw, but in protocols on top of HTTP the received wisdom is to side with legible strings over opaque enumerations.


  • Translate

    I would still use enumeration internally but would expect consumers to pass me only the name, not the numeric value itself.

    just some silly example to illustrate:

    public enum DocumentType
    {
      Invoice,
      Contract,
      WorkOrder,
      SignedWorkOrder
    }
    
    [WebMethod]
    public void UploadDocument(string type, byte[] data)
    {
      DocumentType docType = (DocumentType)Enum.Parse(typeof(DocumentType), type);
    }
    

  • Translate

    In .NET, enumeration values are (by default) serialized into xml with the name. For instances where you can have multiple values (flags), then it puts a space between the values. This works because the enumeration doesn't contain spaces, so you can get the value again by splitting the string (ie. "Invoice Contract SignedWorkOrder", using lubos's example).

    You can control the serialization of values of in asp.net web services using the XmlEnumAttribute, or using the EnumMember attribute when using WCF.


  • Translate

    If you are consuming your Web service from a .NET page/application, you should be able to access the enumeration after you add your Web reference to the project that is consuming the service.


  • Translate

    If you are not working with .NET to .NET SOAP, you can still define an enumerator provided both endpoints are using WSDL.

    <s:simpleType name="MyEnum">    
         <s:restriction base="s:string">
              <s:enumeration value="Wow"/>
              <s:enumeration value="This"/>
              <s:enumeration value="Is"/>
              <s:enumeration value="Really"/>
              <s:enumeration value="Simple"/>
         </s:restriction>
    </s:simpleType>
    

    Its up to the WSDL -> Proxy generator tool to parse that into a enum equivalent in the client language.


  • Translate

    There are some fairly good reasons for not using enums on an interface boundary like that. Consider Dare's post on the subject.


  • Translate

    I've noticed that when using "Add Service Reference" as opposed to "Add Web Reference" from VS.net, the actual enum values come across as well as the enum names. This is really annoying as I need to support both 2.0 and 3.5 clients. I end up having to go into the 2.0 generated web service proxy code and manually adding the enum values every time I make a change!