2016-06-23 18 views
0

Ich versuche, vom programmgesteuerten Festlegen des Endpunkts auf die Verwendung der Konfigurationsdatei. Das Problem ist, dass, wenn ich die Konfigurationsdatei verwende, kein Fehler ausgelöst wird, aber der TCP-Port nicht geöffnet wird und Clients keine Verbindung herstellen können.net.tcp funktioniert, wenn programmgesteuert festgelegt, aber nicht bei Verwendung der Konfigurationsdatei

Dies ist netstat zeigt den Port geöffnet wird, wenn programmgesteuert gesetzt, und dann mit der Konfigurationsdatei. netstat output

Das folgende ist mein komplettes Beispiel Client-Server und Verträge app.config

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.serviceModel> 
     <services> 
      <service name="Server.CustomerService"> 
       <endpoint 
        address="net.tcp://localhost:8081/CustomerService" 
        binding="netTcpBinding" 
        contract="Shared.ICustomerService"/> 
      </service> 
     </services> 
    </system.serviceModel> 
</configuration> 

Server:

class ProgramService 
    { 
     static List<Customer> _customers = new List<Customer>(); 
     static void Main(string[] args) 
     { 
      CreateCustomers(); 
      Uri netTCPObject = new Uri("net.tcp://localhost:8081/CustomerService"); 
      ServiceHost sessionHost = new ServiceHost(typeof(CustomerService), netTCPObject); 
      //ServiceHost sessionHost = new ServiceHost("Server.CustomerService"); //using the app.config 

      sessionHost.Open(); 

      Console.WriteLine("Service is running"); 
      Console.ReadLine(); 
      sessionHost.Close(); 
     } 

     private static void CreateCustomers() 
     { 
      _customers.Add(new Customer() { CustomerId = 1, FirstName = "Fred", LastName = "Flintstone" }); 
      _customers.Add(new Customer() { CustomerId = 2, FirstName = "John", LastName = "Doe" }); 
      _customers.Add(new Customer() { CustomerId = 3, FirstName = "Rebecca", LastName = "Johndaughter" }); 
      _customers.Add(new Customer() { CustomerId = 4, FirstName = "Julie", LastName = "Herald" }); 
     } 

     public class CustomerService : ICustomerService 
     { 
      public Customer GetCustomer(int customerId) 
      { 
       return _customers.FirstOrDefault(c => c.CustomerId == customerId); 
      } 

      public bool UpdateCustomer(Customer customer) 
      { 
       var curCust = _customers.FirstOrDefault(c => c.CustomerId == customer.CustomerId); 
       if (curCust != null) 
       { 
        curCust.FirstName = customer.FirstName; 
        curCust.LastName = customer.LastName; 
       } 
       else 
       { 
        _customers.Add(customer); 
       } 
       return true; 
      } 
     } 
    } 

Verträge:

namespace Shared 
{ 
    [ServiceContract()] 
    public interface ICustomerService 
    { 
     [OperationContract] 
     Customer GetCustomer(int customerId); 

     [OperationContract] 
     bool UpdateCustomer(Customer customer); 
    } 

    [DataContract] 
    public class Customer 
    { 
     [DataMember] 
     public string FirstName { get; set; } 

     [DataMember] 
     public string LastName { get; set; } 

     [DataMember] 
     public int CustomerId { get; set; } 
    } 
} 

Auftraggeber:

class ProgramClient 
{ 
    static void Main(string[] args) 
    { 
     //http://stackoverflow.com/a/2943206/232226 
     NetTcpBinding binding = new NetTcpBinding(); 
     EndpointAddress endpoint = new EndpointAddress("net.tcp://localhost:8081/CustomerService"); 
     ChannelFactory<ICustomerService> factory = new ChannelFactory<ICustomerService>(binding, endpoint); 

     ICustomerService service = factory.CreateChannel(); 
     for (int i = 1; i < 5; i++) 
     { 
      Customer customer = service.GetCustomer(i); 
      Console.WriteLine(String.Format(" Customer {0} {1} received.", customer.FirstName, customer.LastName)); 
     } 
     Console.ReadLine(); 
    } 
} 
+0

Da Ihr konfiguriert Dienstname mit dem Namen entspricht nicht von der Dienstleistung. Es sollte '' sein. – CodeCaster

+0

Mit dem String-Konstruktor können Sie also nicht den von Ihnen gewünschten Namen verwenden? neuer ServiceHost ("Server.CustomerService"); – ToddK

+0

Also tat ich wie vorgeschlagen, den Namen in der Konfiguration ändern und den Namen im ServiceHost-Konstruktor aktualisieren, aber das half nicht. Hinweis: Um dieses Beispiel mit der Konfigurationsdatei auszuführen, müssen Sie die zweite Instance ServiceHost auskommentieren und die erste Instanz auskommentieren. – ToddK

Antwort

1

ServiceHost Der Konstruktor hat eine Überlastung Akzeptieren eines Type und man ein object Annahme, wobei entweder eine Art oder eine Instanz einer Dienstklasse.

Das bedeutet, dass new ServiceHost("someString") die object Überladung aufrufen wird, die eine Ausnahme auslösen wird, weil string keinen Dienst implementiert.

Sie müssen es mit Ihren Service-Typ nennen:

var serviceHost = new ServiceHost(typeof(CustomerService)) 

Und in der Konfiguration, die full name des Typs verwenden:

<service name="ServiceNamespace.ProgramService.CustomerService">