We are consuming an ASMX service by adding a WCF "Service Reference" to our project. When we do this, by default it is supposed to use the DataContractSerializer
and if something goes wrong, it will fall back to the XmlSerializer
.
I've tried forcing the DataContractSerializer
when generating the proxy classes, but when I do that, they are incomplete and missing all of the custom classes used by the webservice (leaving only the interface for the Soap, SoapChannel, and the SoapClient class).
Well, something is going wrong and it is falling back to the use the XmlSerializer
. I do not see any errors or warnings when I generate the reference.
How can I find out what is causing the DataContractSerializer
to fail and fall back to the XmlSerializer
?
Long story short is that we were unable to force VS to use the DataContractSerializer. Instead we ended up writing our own WCF Service Contracts that represented the webservice. When we consume the service we are instead creating the ChannelFactory generically by using our OWN Service Contracts. Below is the code that we used to create the channel.
/// <summary>
/// A generic webservice client that uses BasicHttpBinding
/// </summary>
/// <remarks>Adopted from: http://blog.bodurov.com/Create-a-WCF-Client-for-ASMX-Web-Service-Without-Using-Web-Proxy/
/// </remarks>
/// <typeparam name="T"></typeparam>
public class WebServiceClient<T> : IDisposable
{
private readonly T channel;
private readonly IClientChannel clientChannel;
/// <summary>
/// Use action to change some of the connection properties before creating the channel
/// </summary>
public WebServiceClient(string endpointUrl, string bindingConfigurationName)
{
BasicHttpBinding binding = new BasicHttpBinding(bindingConfigurationName);
EndpointAddress address = new EndpointAddress(endpointUrl);
ChannelFactory<T> factory = new ChannelFactory<T>(binding, address);
this.clientChannel = (IClientChannel)factory.CreateChannel();
this.channel = (T)this.clientChannel;
}
/// <summary>
/// Use this property to call service methods
/// </summary>
public T Channel
{
get { return this.channel; }
}
/// <summary>
/// Use this porperty when working with Session or Cookies
/// </summary>
public IClientChannel ClientChannel
{
get { return this.clientChannel; }
}
public void Dispose()
{
this.clientChannel.Dispose();
}
}