Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using C# Service Reference with Proxy

I am trying to use a ServiceReference in a C# project. The project is intended to test a connection. I have a customer who is trying to connect with a C# application to one web service of one of my colleagues. The connection can't be established and he is assuming that it is our own mistake.

I am trying to write now a simple C# project. Thats enough of story... now the Information needed.

  1. The customer uses a Proxy server
  2. I try to connect to this web service for testing reasons http://www.w3schools.com/webservices/tempconvert.asmx
  3. I Use .Net Framework 4.0
  4. My Project compiles into a Windows Forms application.

Here The source code of my Method:

    private void button2_Click(object sender, EventArgs e)
    {
        try
        {
            //Create Client
            ServiceReference1.TempConvertSoapClient client = new ServiceReference1.TempConvertSoapClient(@"TempConvertSoap",@"http://www.w3schools.com/webservices/tempconvert.asmx");
            if (client.ClientCredentials != null)
            {
                //Use Values which are typed in in the GUI
                string user = tbUser.Text;
                string password = tbPassword.Text;
                string domain = tbDomain.Text;

                //Check what information is used by the customer.
                if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(domain))
                {
                    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential(user, password, domain);
                }
                if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password))
                {
                    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential(user, password);
                }
            }
            //Oh nooo... no temperature typed in
            if (string.IsNullOrEmpty(tbFahrenheit.Text))
            {
                //GOOD BYE
                return;
            }
            //Use the webservice 
            string celsius =  client.FahrenheitToCelsius(tbFahrenheit.Text); //<-- Simple Calculation
            tbCelsius.Text = celsius;
        }
        catch(Exception ex) 
        {
            //Something 
            MessageBox.Show(ex.ToString());
        }

    }

Here is my Question: How can i set a proxy to this service reference or rather the client ? There is no property or setter for this purpose. I tried it with the ClientCredentials

like image 875
Bongo Avatar asked Jul 30 '13 11:07

Bongo


2 Answers

Okay i found the answer myself. Hopefully it will help somebody ;).

This part creates a binding. This can later be used in the webservice

    private void button2_Click(object sender, EventArgs e)
    {
        BasicHttpBinding binding = new BasicHttpBinding("TempConvertSoap");

        if (!string.IsNullOrEmpty(tbProxy.Text))
        {
            binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            binding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.Basic;


            string proxy = string.Format("http://{0}", tbProxy.Text);
            if (!string.IsNullOrEmpty(tbPort.Text)) 
            {
               proxy = string.Format("{0}:{1}",proxy,tbPort.Text);
            }

            binding.UseDefaultWebProxy = false;
            binding.ProxyAddress = new Uri(proxy);


        }
        EndpointAddress endpoint = new EndpointAddress(@"http://www.w3schools.com/webservices/tempconvert.asmx");

Here begins the old part where i set the binding .

            try
        {
            //Create Client
            ServiceReference1.TempConvertSoapClient client = new ServiceReference1.TempConvertSoapClient(binding, endpoint);
            if (client.ClientCredentials != null)
            {
                //Use Values which are typed in in the GUI
                string user = tbUser.Text;
                string password = tbPassword.Text;
                string domain = tbDomain.Text;



                client.ClientCredentials.UserName.UserName = user;
                client.ClientCredentials.UserName.Password = password;
                client.ClientCredentials.Windows.ClientCredential.Domain = domain;

                //Check what information is used by the customer.
                if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password) && !string.IsNullOrEmpty(domain))
                {
                    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential(user, password, domain);
                }
                if (!string.IsNullOrEmpty(user) && !string.IsNullOrEmpty(password))
                {
                    client.ClientCredentials.Windows.ClientCredential = new NetworkCredential(user, password);
                }
            }
            //Oh nooo... no temperature typed in
            if (string.IsNullOrEmpty(tbFahrenheit.Text))
            {
                //GOOD BYE
                return;
            }
            //Use the webservice 

            //THIS ONE IS IMPORTANT
            System.Net.ServicePointManager.Expect100Continue = false;
            string celsius =  client.FahrenheitToCelsius(tbFahrenheit.Text); //<-- Simple Calculation
            tbCelsius.Text = celsius;
        }
        catch(Exception ex) 
        {
            //Something 
            tbCelsius.Text = ex.Message;
            MessageBox.Show(ex.ToString());
        }

    }

I used Squid as my proxy and use a firewall besides the proxy. After i configured it succesfully i encountered the error (417) Expectation failed. During the research i found a line of code which helped me to "resolve" this problem

System.Net.ServicePointManager.Expect100Continue = false;
like image 85
Bongo Avatar answered Oct 31 '22 19:10

Bongo


It's and old question but still relevant. The accepted answer works, but I managed to resolve this with a different approach. When you add service reference to your project, Visual Studio will add bindings and endpoint addresses etc to web.config/app.config (depending on the application type). You can add the proxy configuration (ip and port) directly to the config file so that you won't need to do anything special on the code side:

  <system.serviceModel>
    <bindings>
      <basicHttpBinding>        
        <binding name="MyServiceBinding" 
            proxyAddress="http://123.123.12.1:80" useDefaultWebProxy="false" />
      </basicHttpBinding>
    </bindings>
    <client>    
      <endpoint address="http://address.com/endpoint"
        binding="basicHttpBinding" bindingConfiguration="MyServiceBinding"
        contract="..." name="..." />
    </client>
  </system.serviceModel>

So change the ip and port to your proxy servers ip and port and remember to use useDefaultWebProxy="false" so that the application will use that proxy with this service reference.

Reference for basicHttpBinding.

like image 6
Esko Avatar answered Oct 31 '22 21:10

Esko