17
votes

I've found that I can import a SOAP/WSDL service that I plan on using into my solution either as a "Web Service Reference" (System.Web.Services) or as a "Service Reference" (System.ServiceModel / WCF).

I was wondering if what the differences were. I understand that 'Add Service Reference'/WCF is newer, are there any disadvantages to using it over System.Web.Services or is it now the preferred way of consuming SOAP services in .Net?

3

3 Answers

20
votes

The preferred and most useful way is indeed to use Add Service Reference. This will add your service as WCF client side proxy.

Add Web Reference is the "old-style" ASMX/ASP.NET webservice way of doing things.

WCF is the much better choice than ASMX, because:

  • it's newer and will be supported in the future (ASMX is on the way out); if you learn it now, you won't have to learn it later when ASMX is definitely gone
  • it offers much more flexibility in every aspect
  • you can only ever host an ASMX service is IIS, using HTTP as your protocol; WCF can be hosted in IIS; self-hosted in a Windows NT Service; WCF can use HTTP, NetTCP, MSMQ and many more protocols
  • WCF offers a lot more security and other settings, making it much more powerful to use

Yes, WCF has a bad rap about being really hard to learn - I don't really find that to be true. Check out those beginner's resources - very useful indeed!

6
votes

I have an application that's calling an existing SOAP service that's written in J2EE and hosted in WebSphere.

I've created two console applications - one referencing the service as an old school Web Service and another that references it as a Service Reference.

In both cases, Visual Studio creates a proxy class and appropriate configuration entries for the service.

In the Service Reference console app, I get a lot more configuration options that I don't see in the Web Service app. In particular, I can set the maximum message size, etc.

In fact, in order to get the Service Reference console app to work properly, I had to increase the default message size in order to get back all the data sent in one of the method calls.

Here's what the configuration looks like in the Service Reference app:

<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
                <binding name="ClaimSoapBinding" closeTimeout="00:01:00" openTimeout="00:01:00"
                    receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
                    bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
                    maxBufferSize="65536000" maxBufferPoolSize="524288" maxReceivedMessageSize="65536000"
                    messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
                    useDefaultWebProxy="true">
                    <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
                        maxBytesPerRead="4096" maxNameTableCharCount="16384" />
                    <security mode="None">
                        <transport clientCredentialType="None" proxyCredentialType="None"
                            realm="" />
                        <message clientCredentialType="UserName" algorithmSuite="Default" />
                    </security>
                </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://urlgoeshere/ClaimService"
                binding="basicHttpBinding" bindingConfiguration="ClaimSoapBinding"
                contract="ClaimService.Claim" name="ClaimService" />
        </client>
    </system.serviceModel>
</configuration>

In my old school Web Service console app, I didn't have to alter the configuration at all to get back the giant set of data sent back. Here's what its configuration looks like:

<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ServiceTesterOldSchool.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <applicationSettings>
        <ServiceTesterOldSchool.Properties.Settings>
            <setting name="ServiceTesterOldSchool_ClaimService_ClaimService"
                serializeAs="String">
                <value>http://urlgoeshere/ClaimService</value>
            </setting>
        </ServiceTesterOldSchool.Properties.Settings>
    </applicationSettings>
</configuration>

It's much simpler, but lacks a lot of the options we get with Service References.

The actual code calling the service is nearly identical in both cases.

To answer your question, though, I think it's important to stick with the current way of doing things. Microsoft kinda makes this clear by forcing you to go through a couple levels of dialogs before you can even add a old school Web Reference (at least in VS2008).

I think the WCF way is more flexible, and the configuration is a lot more descriptive about what's going on.

Also, as you add new WCF components to your apps, it'll be nice to keep your configuration settings consistent, instead of mixing and matching between old school and WCF.

3
votes

I think one of the differences is in the autogenerated proxy code for the service. If you go with the service reference, your application will require the WCF layer to communicate. This generally isn't a problem, but if you are writing code that will be run on other platforms (like Mono) you will want to use the web service reference instead (since Mono doesn't support WCF yet.)