views:

1595

answers:

2

Hi,

I have a WCF service that works ok if I create the service without specifying any binding or endpoint (it reads it from the generated values in the App.config when I registered the WCF via Visual Studio).

I have a simple method that returns the service reference:

return new SmsServiceReference.SmsEngineServiceClient();

This works ok (because the values are read from the config). However, I'd like to have some of these values in a Database (the URI for example) and would like to do something like this:

        Binding binding = new BasicHttpBinding();
        EndpointAddress endpointAddress = new EndpointAddress( "my.uri.com/service.svc" );

        return new SmsServiceReference.SmsEngineServiceClient(binding,endpointAddress);

This doesn't work. It throws an exception when I try to use the service reference.

I suspect that this is because my App.config has more information that the two lines up there are not providing (obviously). The question is, how can I replicate the following App.Config values programatically?

Here's the fragment of my App.Config: (the URI has been altered to protect the inocent).

  <system.serviceModel>
<bindings>
  <basicHttpBinding>
    <binding name="BasicHttpBinding_ISmsEngineService" 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://www.myuri.com/Services/Services.svc/basic"
      binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_ISmsEngineService"
      contract="SmsServiceReference.ISmsEngineService" name="BasicHttpBinding_ISmsEngineService" />
</client>

+1  A: 

Well, the client endpoint in the config specifies this URL:

 <endpoint address="http://www.myuri.com/Services/Services.svc/basic"

but in your code sample, you create:

 EndpointAddress endpointAddress = new EndpointAddress( "my.uri.com/service.svc" );

The addresses must match - if the one in the config works, you'll need to change your code to:

 EndpointAddress endpointAddress = new EndpointAddress( "http://www.myuri.com/Services/Services.svc/basic" );

Mind you - there are various little typos in your code sample (my.uri.com vs. www.myuri.com, /service.svc instead of /Services/Services.svc).

Does it work with the corrected endpoint address?

Marc

marc_s
I apologize for the "little typos", I was just trying to be "simple". The endpoint address use in code (and in the app config) are the same, yet it doesn't work. There's one difference, the App.config has the /basic thing. That's not part of the URI, dunno why VSTUDIO added that. If you browse to that url (with /basic) it doesn't work. Needless to say, I've tried both. I assume that I'm missing something in my "endpoint" creation that the App.config has. In fact, I am not giving my end point any parameter but the uri, what about all the other APp.config info?
Martín Marconcini
The exact spelling of the URL is crucial, so being "simple" here is leading to confusion. Can you show us the config file for the server part?
marc_s
Hi marc, the problem was not the URI, but some parameters I had in my client web.config that I was not passing to the binding when creating it programatically. I passed everything exactly as it was in the web.config (by using Emmanuel's suggestion) and it worked. Thanks for your help! +1 for you
Martín Marconcini
+4  A: 

Most of the values in the App config are also properties in the binding and can be recreated programatically. Personally, I use a method such as the one below to create the binding


 public static BasicHttpBinding CreateBasicHttpBinding()
        {
            BasicHttpBinding binding = new BasicHttpBinding();
            binding.AllowCookies = false;
            binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
            binding.OpenTimeout = new TimeSpan(0, 1, 0);
            binding.SendTimeout = new TimeSpan(0, 1, 0);
            // add more based on config file ...
            //buffer size
            binding.MaxBufferSize = 65536;
            binding.MaxBufferPoolSize = 534288;
            binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;

            //quotas
            binding.ReaderQuotas.MaxDepth = 32;
            binding.ReaderQuotas.MaxStringContentLength = 8192;
            // add more based on config file ...

            return binding;
        }

And I use something like this for creating my Endpoint address


public static EndpointAddress CreateEndPoint()
        {
            return new EndpointAddress(Configuration.GetServiceUri());
        }

The serviceUri will be the service URL such as http://www.myuri.com/Services/Services.svc/basic

Finally to create the service client


 Binding httpBinding = CreateBasicHttpBinding();
 EndpointAddress address = CreateEndPoint();
 var serviceClient = new MyServiceClient(httpBinding, address);

Emmanuel
This did the trick. Thanks.
Martín Marconcini