5

Please excuse this question from an extreme newbie. I couldn't find the answer anywhere else.

I am writing a solution using Entity Framework and WCF. I will be writing several different clients. I have placed the database connection string in both the Entity Framework project's app.config and the WCF host's app.config file.

In the host class, I wrote a simple test service contract with one method that simply retrieves all the customers from the database (from EF), called GetAllCustomers(). I then wrote a simple console client app to call GetAllCustomers() of the host and write all the customers' first and last names to the console.

When I tried running the client, I got an error that says, "No connection string named 'TRS11Entities' could be found in the application config file.

If I copy the connection string to the client console app's app.config file, it works fine, but if I comment it out, it doesn't work again.

Since the WCF host is doing the talking to the database, not the client directly, I don't understand why the client would need a connection string. I can only guess that the connection string is being passed up the chain from the client to the WCF host to Entity Framework. How can I make the WCF host tell .NET, "The buck stops here! Use my app.config's connection string and stop bothering the client for this info!"

If it matters, I'm using Visual Studio Pro 2012, with all projects written in C# and targeting the V4.5 .NET framework.

From APP.CONFIG in the WCF service project:

  <system.serviceModel>
    <services>
      <service name="OrsonServiceLibrary.Service1">
        <endpoint address="localhost" binding="basicHttpBinding" name="TRS11Entities"
          contract="OrsonServiceLibrary.IService1">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/Design_Time_Addresses/OrsonServiceLibrary/Service1/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, 
          set the values below to false before deployment -->
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <!-- To receive exception details in faults for debugging purposes, 
          set the value below to true.  Set to false before deployment 
          to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>
  <connectionStrings>
    <add name="TRS11Entities" connectionString="metadata=res://*/TRS11Model.csdl|res://*/TRS11Model.ssdl|res://*/TRS11Model.msl;provider=FirebirdSql.Data.FirebirdClient;provider connection string='character set=NONE;data source=localhost;initial catalog=&quot;C:\Program Files (x86)\TRS11\Data\DATA1100.FDB&quot;;user id=sysdba;password=masterkey'" providerName="System.Data.EntityClient" />
  </connectionStrings>

From APP.CONFIG in the Entity Framework project:

  <configSections>
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
  </configSections>
  <connectionStrings>
    <add name="TRS11Entities" connectionString="metadata=res://*/TRS11Model.csdl|res://*/TRS11Model.ssdl|res://*/TRS11Model.msl;provider=FirebirdSql.Data.FirebirdClient;provider connection string='initial catalog=&quot;C:\Program Files (x86)\TRS11\Data\DATA1100.FDB&quot;;user id=sysdba;password=masterkey;data source=localhost'" providerName="System.Data.EntityClient" />
  </connectionStrings>
  <entityFramework>
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
      <parameters>
        <parameter value="v11.0" />
      </parameters>
    </defaultConnectionFactory>
  </entityFramework>

From APP.CONFIG in the console client app:

  <system.serviceModel>
    <client>
      <endpoint address="http://localhost:8000/Service1" contract="OrsonServiceLibrary.IService1" binding="basicHttpBinding" />
    </client>
  </system.serviceModel>

  <!--<connectionStrings>
    <add name="TRS11Entities" connectionString="metadata=res://*/TRS11Model.csdl|res://*/TRS11Model.ssdl|res://*/TRS11Model.msl;provider=FirebirdSql.Data.FirebirdClient;provider connection string='character set=NONE;data source=localhost;initial catalog=&quot;C:\Program Files (x86)\TRS11\Data\DATA1100.FDB&quot;;user id=sysdba;password=masterkey'" providerName="System.Data.EntityClient" />
  </connectionStrings>-->

Code for GetAllCustomers() function in the WCF Service project:

public HashSet<CUSTOMER> GetAllCustomers()
{
    var db = new TRS11Entities();

    HashSet<CUSTOMER> TheCusts = new HashSet<CUSTOMER>();

    foreach (CUSTOMER c in db.CUSTOMERs)
    {
        TheCusts.Add(c);
    }

    return TheCusts;
}

Console client app code:

static void Main(string[] args)
{
    Console.WriteLine("Press Enter to begin.");
    Console.ReadLine();

    Service1 MyService = new Service1();

    HashSet<CUSTOMER> cl = MyService.GetAllCustomers();

    foreach (CUSTOMER c in cl)
    {
        Console.WriteLine(c.CUSTFNAME + " " + c.CUSTLNAME);
    }

    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
}

Host application code:

class Program
{
    static void Main(string[] args)
    {
        ServiceHost hostA = null;

        try
        {
            hostA = new ServiceHost(typeof(Service1));
            hostA.Open();

            Console.WriteLine();
            Console.WriteLine("Host started.  Press Enter to terminate host.");
            Console.ReadLine();

        }
        finally
        {
            if (hostA.State == CommunicationState.Faulted)
                hostA.Abort();
            else
                hostA.Close();
        }
    }
}

Thanks, Joe

JoeMjr2
  • 3,804
  • 4
  • 34
  • 62
  • Oh, I just also thought I'd mention, in case it matters... I don't have a host app yet for the WCF service. So far, it's just a WCF class library, and I'm hosting it in the WCF Service Host for testing. -Joe – JoeMjr2 Dec 28 '12 at 06:50
  • Just because I thought the WCF Service Host might be the issue, I went ahead and write a simple host EXE to host the service. I put the connection string in the host app's app.config file, but I still get the error. – JoeMjr2 Dec 28 '12 at 07:30
  • 1
    Welcome to stack overflow! When asking questions, rather than describe the code you wrote, it is better to actually post it along with your question. In this case I would like to see your config sections (the bits dealing with connection string), and the code you are using to extract them. Thanks. – tom redfern Dec 28 '12 at 08:11

3 Answers3

2

Something tells me, that you're actually creating an instance of the service in your client app instead of using a proxy/channel.

What is the Service1 type in the client app code? Is it OrsonServiceLibrary.Service1 ?

Service1 MyService = new Service1();

If so, just remove reference to the service project and Add Service Reference instead. This will generate a proxy, which you can use for accessing your service.

Alex Pokislyuk
  • 213
  • 3
  • 8
  • Yes, that was it! I had created the service reference, but I had also added a reference to the service project, and was instantiating that instead of the proxy. Thanks! – JoeMjr2 Dec 30 '12 at 07:51
1

The client app isn't passing the connection to your wcf service. My guess is that you are making an un-intentional call to your database in your client app. That would explain the error and why it works when you add the connection string to your console app.

Hope that helps. Post some code and we may be able to help more.

Ben Tidman
  • 2,129
  • 17
  • 30
  • Thanks. I have added what I think are the relevant parts of my code to my original question. Let me know if I should post any other code. – JoeMjr2 Dec 29 '12 at 03:41
0

Without code it makes answering your question much harder, However, I suspect your issue is you have your connection string in a library app config file. The distinction here is that when you run the program the settings are loaded from the executing assembly app config file.

Check that the settings are in the "MyApp.exe.config" file.

Jake1164
  • 12,291
  • 6
  • 47
  • 64
  • 1
    This might also be of interest concerning config files for multiple libraries. http://stackoverflow.com/questions/5674971/app-config-for-a-class-library – Jake1164 Dec 28 '12 at 13:36