在运行时更改ServiceHost端点地址C#

在运行时更改ServiceHost端点地址C#,c#,wcf,service,servicehost,C#,Wcf,Service,Servicehost,我正忙于编写一个文件服务器/客户机工具,它基本上使用托管服务向服务器发送和接收数据。由于此解决方案将被许多不同的人使用,因此让他们去编辑安装程序的App.Config文件并不明智。我想做的是在运行时更改此设置,以便用户能够完全控制要使用的设置。这是我的App.Config文件: <system.serviceModel> <services> <service name="FI.ProBooks.FileSystem.File

我正忙于编写一个文件服务器/客户机工具,它基本上使用托管服务向服务器发送和接收数据。由于此解决方案将被许多不同的人使用,因此让他们去编辑安装程序的App.Config文件并不明智。我想做的是在运行时更改此设置,以便用户能够完全控制要使用的设置。这是我的App.Config文件:

<system.serviceModel>
        <services>
            <service name="FI.ProBooks.FileSystem.FileRepositoryService">
                <endpoint name="" binding="netTcpBinding"
                    address="net.tcp://localhost:5000"
                    contract="FI.ProBooks.FileSystem.IFileRepositoryService"
                    bindingConfiguration="customTcpBinding" />
            </service>
        </services>
        <bindings>
            <netTcpBinding>
                <binding name="customTcpBinding" transferMode="Streamed" maxReceivedMessageSize="20480000" />
            </netTcpBinding>
        </bindings>
    </system.serviceModel>


我想做的是只更改地址(在本例中为net)。tcp://localhost:5000)当应用程序被执行时。因此,我必须能够读取当前值并将其显示给用户,然后获取他们的输入并将其保存回该字段。

您可以创建提供配置名称和端点的服务实例。所以你可以使用

EndpointAddress endpoint = new EndpointAddress(serviceUri);
var client= new MyServiceClient(endpointConfigurationName,endpoint )

看看这篇文章。

下面的测试可能会对你有所帮助。基本上,这些步骤是

  • 实例化从.config文件读取配置的主机实例
  • 使用与旧配置相同的配置创建
    EndpointAddress
    的新实例,但更改uri并将其分配给
    ServiceEndpoint
    Address
    属性

    [TestMethod]
    public void ChangeEndpointAddressAtRuntime()
    {
        var host = new ServiceHost(typeof(FileRepositoryService));
    
        var serviceEndpoint = host.Description.Endpoints.First(e => e.Contract.ContractType == typeof (IFileRepositoryService));
        var oldAddress = serviceEndpoint.Address;
        Console.WriteLine("Curent Address: {0}", oldAddress.Uri);
    
        var newAddress = "net.tcp://localhost:5001";
        Console.WriteLine("New Address: {0}", newAddress);
        serviceEndpoint.Address = new EndpointAddress(new Uri(newAddress), oldAddress.Identity, oldAddress.Headers);
        Task.Factory.StartNew(() => host.Open());
    
        var channelFactory = new ChannelFactory<IFileRepositoryService>(new NetTcpBinding("customTcpBinding"), new EndpointAddress(newAddress));
        var channel = channelFactory.CreateChannel();
    
        channel.Method();
    
        (channel as ICommunicationObject).Close();
    
    
        channelFactory = new ChannelFactory<IFileRepositoryService>(new NetTcpBinding("customTcpBinding"), oldAddress);
        channel = channelFactory.CreateChannel();
    
        bool failedWithOldAddress = false;
        try
        {
            channel.Method();
        }
        catch (Exception e)
        {
            failedWithOldAddress = true;
        }
    
        (channel as ICommunicationObject).Close();
    
        Assert.IsTrue(failedWithOldAddress);  
    }
    
    [TestMethod]
    public void ChangeEndpointAddressAtRuntime()
    {
    var host=新的服务主机(typeof(FileRepositoryService));
    var serviceEndpoint=host.Description.Endpoints.First(e=>e.Contract.ContractType==typeof(IFileRepositoryService));
    var oldAddress=serviceEndpoint.Address;
    WriteLine(“当前地址:{0}”,oldAddress.Uri);
    var newAddress=“net。tcp://localhost:5001";
    WriteLine(“新地址:{0}”,newAddress);
    serviceEndpoint.Address=新端点地址(新Uri(newAddress)、oldAddress.Identity、oldAddress.Header);
    Task.Factory.StartNew(()=>host.Open());
    var channelFactory=新的channelFactory(新的NetTcpBinding(“customTcpBinding”)、新的EndpointAddress(newAddress));
    var channel=channelFactory.CreateChannel();
    channel.Method();
    (通道作为ICommunicationObject)。关闭();
    channelFactory=新的channelFactory(新的NetTcpBinding(“customTcpBinding”)、旧地址;
    channel=channelFactory.CreateChannel();
    bool failedWithOldAddress=false;
    尝试
    {
    channel.Method();
    }
    捕获(例外e)
    {
    failedWithOldAddress=true;
    }
    (通道作为ICommunicationObject)。关闭();
    Assert.IsTrue(使用旧地址失败);
    }
    

问题是关于服务主机而不是客户的。您不喜欢所有的var,但您的回答总体上很有帮助,谢谢。