WCF: How can I programmatically recreate these App.config values?

10,065

Solution 1

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);

Solution 2

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

Share:
10,065
Martin Marconcini
Author by

Martin Marconcini

Android developer (Kotlin/Java) and some Flutter (newbie). Did iOS (Swift) for a while, not really up to date with the latest Swift. I'm very interested in doing Rust, but I haven't found a chance to properly learn it and nobody will pay me to do it so... here we are :) I haven't done Objective-C since before ARC. I haven't done C#.NET since .NET 3.5 in 2011. I occasionally use Windows for gaming. I mainly use Linux for everything else (and macOS when I have no choice, which is sometimes the case in some corporate environments). Note to Recruiters: Please don't make me offers that are not 100% remote friendly; I've been working from home since 2001 and I expect to continue to do so, pandemic or not. Coming to an office every now and then or once a week is fine, but it should not be the norm; as a developer, the distractions are too many. I disagree with StackOverflow discontinuing JOBS/Developer Story, so I may not be as active as before on this site.

Updated on July 18, 2022

Comments

  • Martin Marconcini
    Martin Marconcini almost 2 years

    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 programmatically?

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

      <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>
    

  • Martin Marconcini
    Martin Marconcini almost 15 years
    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?
  • marc_s
    marc_s almost 15 years
    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?
  • Martin Marconcini
    Martin Marconcini almost 15 years
    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