Problem 1: You might not always get want you want
When services share types you will have problems because the generated proxies also have client-side representations of the shared types. (BTW, in ASMX 2.0 this is less of a problem, since wsdl.exe has a /sharetypes parameter). You will not be able to pass something like an Order object from service1 to service2.
To work around you can use an entity mapper that takes the shared types and transforms them from the service type to the proxy generated type. There will still be a mismatch in the namespaces, so make sure that you mark the namespace that the XmlSerializer uses for the types that are shared.
Problem 2: Certain concepts are useless in another context
By default the ASMX runtime uses document-literal encoding. The main fault with this default surfaces when you work in the SOA environment. Here you program very close to the message in/message out paradigm (aka message oriented thinking). So you pass in a request object to a service method and get a response object. The default encoding creates a root element inside the SOAP body which tightly couples the operation to the message being exchanged. This needs to be decoupled if you want to reuse the message over different operations.
public class Calculator
Remember that the way you pass the action to perform will shift in the near future to WS-Addressing. Here the action will be part of the message (whereas this isn’t the case now, with a HTTP Header or as first child of the SOAP body).
Problem 3: Breaking a contract can be frightening
Create a contract that is stable. This means you need to think in the wire format of your messages. So you think contract first, whatever way of defining your contract uses (Indigo data contract, WSDL definition or XmlSerializer attributes on classes). You will decouple internal thinking from external representation.
Make your contract explicit and do not rely on implicit parts of the contract. The different artifacts of a contract (service descriptions, messages, and types) can be split into separate parts (WSDL with included WSDL files and included XSD schemas). Last of all, use service interfaces and delegators to the host of the interface implementation. In other words: start thinking about interface delegation to another transport.
This picture describes the mapping of contracts pretty well.
You can see the way SOA concepts map to the contract and then to the Object Oriented world.
Problem 4: Deal with change
Make your contract definition resilient to change by introducing.a “bucket” into your payload. This is the pretty well known way of introducing two XmlAny… attributed parameter to each of your message objects.
public class FindBookMessage
[XmlAttribute] public string version;
public string title;
public string author;
[XmlAnyElement]public XmlElement anyElement;
[XmlAnyAttribute] public XmlAttribute anyAttribute;
The XML serializer provides very loose coupling because it defaults value types and ignores extra parameters passed in the incoming message.