【发布时间】:2016-06-23 18:57:44
【问题描述】:
我正在尝试从以编程方式设置端点切换到使用配置文件。问题是我使用config文件时没有报错,但是tcp端口没有打开,客户端无法连接。
这是 netstat 显示在以编程方式设置时打开的端口,然后是配置文件。
以下是我的完整示例客户端服务器和合同 应用程序配置
<?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>
服务器:
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;
}
}
}
合同:
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; }
}
}
客户:
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();
}
}
【问题讨论】:
-
因为你配置的服务名和服务名不对应。应该是
<service name="ProgramService.CustomerService">。 -
所以使用字符串构造函数,你不能使用任何你想要的名字吗? new ServiceHost("Server.CustomerService");
-
所以,我按照建议做了,更改了配置中的名称,并更新了 ServiceHost 构造函数中的名称,但这并没有帮助。请注意,要使用配置文件运行此示例,您需要取消注释第二个 ServiceHost 实例化并注释掉第一个。
-
我错过了您的服务是一个嵌套类。您的
ProgramService在它自己的命名空间中。您还需要预先添加该命名空间,因此您需要SomeNamespace.ProgramService.CustomerService作为配置中的服务名称。不,您不能只将字符串传递给 ServiceHost,您需要单独传递类型和类型。 -
我的命名空间是 wcfService,所以我将配置更新为:
并将实例更新为:ServiceHost sessionHost = new ServiceHost("wcfService .ProgramService.CustomerService");但这没有帮助。
标签: wcf wcf-binding