Interacting with SOAP web services, such as those built with PHP, from a .NET application is a common task. When these services are protected by HTTP Basic Authentication, configuring the C# client requires a small extra step, but it’s simpler than it might seem.
This guide demonstrates the standard and recommended method for consuming a secure SOAP web service with Basic Auth using C#.
The Challenge: Basic Authentication
When you add a “Service Reference” to a Visual Studio project for a SOAP web service, the generated client doesn’t automatically handle sending authentication credentials. If you try to call a service method directly, you will likely get a (401) Unauthorized
error.
The solution is to explicitly provide the credentials (username and password) to the service client instance.
The Standard and Recommended Method
The base class for generated service clients (System.Web.Services.Protocols.SoapHttpClientProtocol
) has a Credentials
property designed for this exact scenario.
Here’s how to use it:
// 1. Instantiate the service client generated by Visual Studio
var service = new My.Web.Service();
// 2. Create a NetworkCredential object with your username and password
var credentials = new System.Net.NetworkCredential("YOUR_USERNAME", "YOUR_PASSWORD");
// 3. Assign this object to the service's Credentials property
// This is the step that tells .NET to use Basic Authentication
service.Credentials = credentials;
// 4. (Optional but recommended) Enable pre-authentication
// This sends the "Authorization" header on the very first request,
// avoiding an unnecessary round-trip (a 401 challenge followed by the authenticated request).
service.PreAuthenticate = true;
// 5. Call your web service method
// The HTTP request will now include the required authentication header.
var result = service.Method();
This approach is clean, simple, and requires no modifications to the generated code (Reference.cs
). It is therefore robust against updates to the service reference.
Legacy Approach: Overriding GetWebRequest
(Not Recommended)
Another method, sometimes found in older projects, involves directly modifying the Reference.cs
file to override the GetWebRequest
method. This approach is not recommended because any update to the service reference will overwrite your changes.
It consisted of manually adding the Authorization
header. If you encounter it, here is what it looks like (with necessary corrections):
// In the Reference.cs file, inside the service client class...
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
// Get the base web request
HttpWebRequest request = (HttpWebRequest)base.GetWebRequest(uri);
// If pre-authentication is enabled, build the header manually
if (this.PreAuthenticate)
{
NetworkCredential nc = this.Credentials.GetCredential(uri, "Basic");
if (nc != null)
{
byte[] credentialBuffer = new System.Text.UTF8Encoding().GetBytes(nc.UserName + ":" + nc.Password);
request.Headers["Authorization"] = "Basic " + Convert.ToBase64String(credentialBuffer);
}
}
return request;
}
This method is more complex and fragile than using the Credentials
property directly.
Verifying the Request
To confirm that the authentication is working, you can use an HTTP traffic analysis tool like Fiddler or Wireshark. By inspecting the outgoing request, you should see an HTTP header that looks like this:
Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==
The string after Basic
is your username:password
encoded in Base64.
To learn more about how this authentication works, see the Wikipedia page on Basic access authentication.