【问题标题】:net.tcp works when programmatically set, but not when using config filenet.tcp 在以编程方式设置时有效,但在使用配置文件时无效
【发布时间】: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();
    }
}

【问题讨论】:

  • 因为你配置的服务名和服务名不对应。应该是&lt;service name="ProgramService.CustomerService"&gt;
  • 所以使用字符串构造函数,你不能使用任何你想要的名字吗? new ServiceHost("Server.CustomerService");
  • 所以,我按照建议做了,更改了配置中的名称,并更新了 ServiceHost 构造函数中的名称,但这并没有帮助。请注意,要使用配置文件运行此示例,您需要取消注释第二个 ServiceHost 实例化并注释掉第一个。
  • 我错过了您的服务是一个嵌套类。您的 ProgramService 在它自己的命名空间中。您还需要预先添加该命名空间,因此您需要 SomeNamespace.ProgramService.CustomerService 作为配置中的服务名称。不,您不能只将字符串传递给 ServiceHost,您需要单独传递类型和类型。
  • 我的命名空间是 wcfService,所以我将配置更新为: 并将实例更新为:ServiceHost sessionHost = new ServiceHost("wcfService .ProgramService.CustomerService");但这没有帮助。

标签: wcf wcf-binding


【解决方案1】:

ServiceHost 构造函数有一个接受Type 的重载和一个接受object 的重载,可以是服务类的类型或实例。

这意味着new ServiceHost("someString") 将调用object 重载,这将引发异常,因为string 没有实现服务。

你需要用你的服务类型来调用它:

var serviceHost = new ServiceHost(typeof(CustomerService))

在配置中,使用full name的类型:

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

【讨论】:

    猜你喜欢
    • 2012-11-10
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-09
    相关资源
    最近更新 更多