Ok, so the question in the title a little misleading… I actually know why it’s abstract, but what I don’t understand why it was designed that way. It forces me to always subclass it and add my own methods, decorated with SoapMethodAttribute, just so I can send a SoapEnvelope from client to server.
What’s lame about this is that all the information I need to send is in the SoapEnvelope already. I shouldn’t need to pass it through some special method decorated with one attribute to set the SOAP action. I understand that this design is intended to simplify the strongly typed approach that Microsoft seems to be pushing, but if I’ve got an XmlDocument rarin’ to go I should be able to just construct a SoapEnvelope set it up myself and pass the DocumentElement to SetBodyObject. The problem now is, there’s no easy way to make a call to a Request-Response style web method. You can send a SoapEnvelope one way easily using a SoapSender’s Send, but uhh… that unfortunately leaves you without a response. You can also receive a SoapEnvelope easily using SoapReceiver’s Receive. The fact that you can’t SendRequestResponse with SoapClient without subclassing it (because it’s protected) just seems like a silly design decision.
In the end, I end up with a a class like this:
public sealed class MyWebServiceClient : SoapClient
{
public MyWebServiceClient(EndpointReference endpointReference) : base(endpointReference)
{
}[SoapMethod("uri:SomeService:SomeMethod")]
public SoapEnvelope DoSomething(SoapEnvelope requestEnvelope)
{
return base.SendRequestResponse(“DoSomething“, requestEnvelope);
}
}
To call it like this:
XmlDocument document = new XmlDocument();
document.Load("somefile.xml");SoapEnvelope envelope = new SoapEnvelope();
envelope.SetBodyObject(document.DocumentElement);MyWebServiceClient client = new MyWebServiceClient();
client.DoSomething(envelope);
What did writing the proxy really buy me in this case? The following call that I could have written myself much more easily:
envelope.Context.Addressing.Action = new Action("uri:uri:SomeService:SomeMethod");