Invoking SharePoint web services from WCF is fairly easy to do, but I did run in to a few minor gotchas on the way there that beat me up a bit that I would like to share. The SharePoint web services are .NET ASMX web services and the steps to getting this working with Visual Studio 2008 are slightly different than that of Visual Studio 2005.
We start by right-clicking on the "Service References" or "References" from "Solution Explorer" for our solution and selecting "Add Service Reference" from the context menu. This will open the "Add Service Reference" dialog allowing us to enter the necessary information to generate our WCF client code. Also note that you can still add a "Web Reference" and generate proxy code based on the .NET framework 2.0 web services technology, by clicking the "Advanced..." button at the bottom of the "Add Service Reference Dialog" and then clicking the "Add Web Reference..." button at the bottom of the "Service Reference Settings" dialog that will show up. After adding the service reference some configurations will be added to app.config and code will be generated in your projects service reference directory.
If you are using Windows Authentication with SharePoint and you attempt to invoke the service via the newly added reference you will likely receive the following error. "The HTTP request is unauthorized with client authentication scheme 'Anonymous'. The authentication header received from the server was 'Negotiate,NTLM'." We will need to modify the app.config so that the service reference relies on the transport for authentication and uses windows authentication. To do this simply open your application configuration which should look similar to the following:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="QueryServiceSoap" closeTimeout="00:01:00" openTimeout="00:01:00"
receiveTimeout="00:10:00" sendTimeout="00:01:00" allowCookies="false"
bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
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://moss1/_vti_bin/search.asmx binding="basicHttpBinding"
bindingConfiguration="QueryServiceSoap" contract="SearchService.QueryServiceSoap"
name="QueryServiceSoap" />
</client>
</system.serviceModel>
</configuration>
Then change the security and transport settings as follows:
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Windows" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
And finally you are going to have to set the token impersonation level on your client proxy object in your code:
SearchService.QueryServiceSoapClient client = new SearchService.QueryServiceSoapClient();
client.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation;
I have not tested and verified this yet, but you should be able to set the app.config settings for the security mode and transport from code as well.
Currently rated 5.0 by 4 people
- Currently 5/5 Stars.
- 1
- 2
- 3
- 4
- 5