0

I'm working with a 3rd party system that is only accessible through web and service references. While building a Windows Service that handles automated processing I have discovered that if web/service references are used by a solution, they must also be set up in any solution that references the first.

Is there a way to prevent this? I would like to make a class library that will hold all of the actual API calls and use that as a NuGet package without having to also add the references to every project down the road.

EDIT: Here's an example of how I call the API currently:

internal class ApiAccess
{
    private readonly Account_SSPSoapClient _apiAccount;

    public ApiAccess()
    {
        _apiAccount = new Account_SSPSoapClient();
    }

    public string GetAccountId(string accountName)
    {
        return _apiAccount.GetID(accountName);
    }
}
Logarr
  • 2,120
  • 1
  • 17
  • 29

1 Answers1

1

This is a problem, but it's not the problem that it appears to be.

You don't actually need the service reference in all projects which use your code - all you need is some information out of the app.config. Specifically, the binding and endpoint address. You can hardcode them into your code, and then you should be able to reference it just fine.

The simplest case:

var request = new MyServiceRequest { /* set properties here */ };
var client  = MyServiceReferenceClient(new BasicHttpBinding(), new EndpointAddress(@"https://my.service.com/path/to/service"));
var channel = client.ChannelFactory.CreateChannel();
var result  = channel.MyService(request);

You'll want to set some paramenters on the BasicHttpBinding to match what's in the app.config file, and the URL also comes out of there.

See this answer for why it doesn't work by default.


Edit: For your code, you'd just replace new Account_SSPSoapClient(); with something along the lines of:

new Account_SSPSoapClient(new BasicHttpBinding(), new EndpointAddress(@"https://my.service.com/path/to/service"));

Everything else should go the same, but it'll use those values instead of the app.config values (which is what it does with no parameters).

Look in the app.config file for something like:

    <bindings>
        <basicHttpBinding>
            <binding name="LabelRecoveryBinding" 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>

Everything in that corresponds to a property you can set on the BasicHttpBinding object created above - most of it is the default values, but you may want to manually set everything just to be safe.

Likewise, look for

<client>
        <endpoint address="http://153.2.133.60:48010/xoltws_ship/LBRecovery"
            binding="basicHttpBinding" bindingConfiguration="LabelRecoveryBinding"
            contract="UPSLabelRecoveryService.LabelRecoveryPortType" name="LabelRecoveryPort" />
</client>

That tells you what URL to supply to the new EndpointAddress.

Community
  • 1
  • 1
Bobson
  • 13,498
  • 5
  • 55
  • 80
  • Could you elaborate on this slightly? Does that code snippet go into the class library, or the project that references it? – Logarr Mar 13 '13 at 14:37
  • @Logarr - Edited - Does that help? It goes in the class library where you're (presumably) already making the call. – Bobson Mar 13 '13 at 15:01
  • Not really... I've edited the question to show an example of how I call the API right now. I don't see how to apply your method in this case. – Logarr Mar 13 '13 at 15:16
  • @Logarr - Ah, that helps clarify. Edited. – Bobson Mar 13 '13 at 15:31
  • That makes more sense. It's not that I'm completely replacing the app.config, but rather overriding it programmatically. Thank you! – Logarr Mar 13 '13 at 15:38
  • @Logarr - Exactly! By extracting what you need from the config to the code, it can then get compiled and distributed without needing to modify any other app.config files. Glad it helped! – Bobson Mar 13 '13 at 15:48