c# – WebService automated testing – consuming service in Visual Studio yields auth problem for one endpoint


I have been tasked with automating tests for a webservice. Pretty straight forward. What I did was:

  • Add service reference in my project.
  • Write code to execute tests with MSTest unit test framework. While doing this, realize the service is not. Um. Entirely tight. I had to make some changes to Reference.cs to handle responses which are defined in the wsdl as having datetime values but are not present. Keep track of changes so when I have to reload the wsdl, I will know what I have changed. Don’t love. Don’t see alternative. Should not be relevant.
  • Finish creating tests for several of the endpoints in the service.

Get to one which is yielding behavior I do not understand. What I observe when testing what I wrote.

When I run the test which includes the new service call, I receive an error:
Message: 
Test method CcbWebServicesTestingNet.TestDevelopment.AddCustmerDonorConsent threw exception:
System.ServiceModel.FaultException: Parameter contactCustomerResponse in method AddCustomerDonorConsent in service CustomerManagement is null!

Relevant troubleshooting info:

  • Run the same endpoint in SOAPUI with the same inputs. Returns response properly. Cool problem is in my code, of course.
  • Test my code with fiddler open. When I get to the bad call, see enter image description here

Ok unauthorized. Exact same authorization code. And … why is NULL response coming back from my call instead of an auth error as with when I change the user name to user name plus some random characters to demonstrate failure. When I change the user name to something clearly invalid and run a working test, I receive this error:

Test method CcbWebServicesTestingNet.TestDevelopment.AddCustmerDonorConsent threw exception:
System.ServiceModel.Security.MessageSecurityException: The HTTP request is unauthorized with client authentication scheme ‘Ntlm’. The authentication header received from the server was ‘NTLM’. —> System.Net.WebException: The remote server returned an error: (401) Unauthorized.

The code that does the auth work is in this class for the ContactCustomer client type.

    using System.ServiceModel;
using CcbWebServicesTestingNet.ServiceRefCreditCard;
using CcbWebServicesTestingNet.ServiceRefCustomerManagement;
using CcbWebServicesTestingNet.ServiceRefDonor;

namespace CcbWebServicesTestingNet.Model
{
    public static class ComponentClient
    {
        private enum ClientType
        {
            ContactCustomer,
            CustomerCreditCard,
            Donor
        }
        private static BasicHttpBinding _binding;
        private static EndpointAddress _address;
        private static readonly Settings Settings = new Settings();
        public static CustomerCreditCard_PortClient GetClientCreditCardClient()
        {
            SetParameters(ClientType.CustomerCreditCard);
            CustomerCreditCard_PortClient client = new CustomerCreditCard_PortClient(_binding, _address);
            if (client.ClientCredentials != null)
            {
                client.ClientCredentials.Windows.ClientCredential.Domain = Settings.AuthDomain;
                client.ClientCredentials.Windows.ClientCredential.UserName = Settings.AuthUserName;
                client.ClientCredentials.Windows.ClientCredential.Password = Settings.AuthPassword;
            }

            return client;
        }

        public static Donor_PortClient GetClientDonorClient()
        {
            SetParameters(ClientType.Donor);
            Donor_PortClient client = new Donor_PortClient(_binding, _address);
            if (client.ClientCredentials != null)
            {
                client.ClientCredentials.Windows.ClientCredential.Domain = Settings.AuthDomain;
                client.ClientCredentials.Windows.ClientCredential.UserName = Settings.AuthUserName;
                client.ClientCredentials.Windows.ClientCredential.Password = Settings.AuthPassword;
            }

            return client;
        }
        public static CustomerManagement_PortClient GetContactCustomerClient()
        {
            SetParameters(ClientType.ContactCustomer);  
            CustomerManagement_PortClient client = new CustomerManagement_PortClient(_binding, _address);
            if (client.ClientCredentials != null)
            {
                client.ClientCredentials.Windows.ClientCredential.Domain = Settings.AuthDomain;
                client.ClientCredentials.Windows.ClientCredential.UserName = Settings.AuthUserName;
                client.ClientCredentials.Windows.ClientCredential.Password = Settings.AuthPassword;
            }

            return client;
        }

        private static void SetParameters(ClientType clientType)
        {
            string url;
            switch (clientType)
            {
                case ClientType.CustomerCreditCard:
                    url = Settings.CreditCardUrl;
                    break;
                case ClientType.Donor:
                    url = Settings.DonorUrl;
                    break;
                default:
                    url = Settings.CustomerManagementUrl; 
                    break;
            }
            

            _binding = new BasicHttpBinding(BasicHttpSecurityMode.TransportCredentialOnly);
            // Configure transport security
            _binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Ntlm;
            _binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Ntlm;
            _binding.Security.Transport.Realm = "";

            // Configure message security
            _binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;
            _binding.MaxReceivedMessageSize = 65536 * 2;

            _address = new EndpointAddress(url);
        }

        
    }
}

Does anyone have suggestions for what I can look at for troubleshooting? This is new work for me, doing SOAP automation. So don’t assume I know stuff. Any suggestions welcome. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *