如何以编程方式为 WCF 服务设置单个端点

发布于 2024-08-17 14:00:42 字数 904 浏览 8 评论 0原文

我试图允许用户配置 WCF 服务,包括该服务侦听的 IP 和端口号。用户有一个单独的配置应用程序,允许设置这些值,但我遇到的问题是 app.config 必须定义一个端点才能创建新的 ServiceHost 条目...但我的端点正在在单独的配置文件中定义,然后必须在运行时以编程方式绑定。

如果我执行以下操作(基于 如何以编程方式修改WCF app.config 端点地址设置?

        m_SvcHost = new ServiceHost(this);

        if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
        {
            m_SvcHost.AddServiceEndpoint(typeof(IMyService),
                new BasicHttpBinding(),
                Config.ServiceEndpoint);
        }

        m_SvcHost.Open();

服务将侦听 app.config 中定义的 URI 和配置文件中定义的 URI 我无法找到删除原始端点的方法。或者在没有定义端点的情况下创建服务

不是一个选项 - 我需要以编程方式从单独的 XML 配置文件中提取配置的值......

编辑:服务 作为 Windows 服务运行并公开 HTTP 端点,它不是作为 IIS 中托管的 Web 服务运行 - 如果这会改变一切

I'm trying to allow for user configuration of a WCF service, including the IP and port number that the service listens on. The user has a separate config application that allows for these values to be set, but the problem I am running into is that the app.config MUST have an endpoint defined in order to create a new ServiceHost entry...but my endpoint is being defined in a separate configuration file and must then be bound programatically at runtime.

If I do the following (based on How to programatically modify WCF app.config endpoint address setting?:

        m_SvcHost = new ServiceHost(this);

        if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
        {
            m_SvcHost.AddServiceEndpoint(typeof(IMyService),
                new BasicHttpBinding(),
                Config.ServiceEndpoint);
        }

        m_SvcHost.Open();

the service will listen on BOTH the URI defined in the app.config, AND the URI defined in the configuration file. There is no way that I can find to remove the original endpoint or to create the service without an endpoint defined.

Writing to the app.config from the configuration application is not an option - I need to pull the configured value programatically from the separate XML config file....

any thoughts?

EDIT: the service runs as a Windows Service and exposes an HTTP endpoint, it is not running as a web service hosted in IIS - if that changes things at all

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

何其悲哀 2024-08-24 14:00:42

贾斯汀,

这对你有帮助吗?此代码将允许您响应您在 CreateServiceHost() 方法中列出的任何地址。

public class CRSyncServiceHost : ServiceHost
{
    public CRSyncServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }

    protected override void ApplyConfiguration()
    {
        base.ApplyConfiguration();
    }
}

public class CRSyncServiceFactory : ServiceHostFactory
{
    protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        Uri newServiceAddress = new Uri("http://someaddress.com/CRSyncService.svc");
        CRSyncServiceHost newHost = new CRSyncServiceHost(serviceType, newServiceAddress);
        return newHost;
    }
}

<%@ ServiceHost Language="C#" Debug="true" Service="CRSyncService" Factory="CRSyncServiceFactory" CodeBehind="CRSyncService.svc.cs" %>

Justin,

Does this help you? This code will allow you to respond to any address that you list in the CreateServiceHost() method.

public class CRSyncServiceHost : ServiceHost
{
    public CRSyncServiceHost(Type serviceType, params Uri[] baseAddresses) : base(serviceType, baseAddresses) { }

    protected override void ApplyConfiguration()
    {
        base.ApplyConfiguration();
    }
}

public class CRSyncServiceFactory : ServiceHostFactory
{
    protected override System.ServiceModel.ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        Uri newServiceAddress = new Uri("http://someaddress.com/CRSyncService.svc");
        CRSyncServiceHost newHost = new CRSyncServiceHost(serviceType, newServiceAddress);
        return newHost;
    }
}

<%@ ServiceHost Language="C#" Debug="true" Service="CRSyncService" Factory="CRSyncServiceFactory" CodeBehind="CRSyncService.svc.cs" %>
清风无影 2024-08-24 14:00:42

嗯,我没有丰富的 WCF 背景,但这行得通吗?

m_SvcHost = new ServiceHost(this);
m_SvcHost.Description.Endpoints.Clear(); // <-- added

if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
{
    m_SvcHost.AddServiceEndpoint(typeof(IMyService),
        new BasicHttpBinding(),
        Config.ServiceEndpoint);
}

m_SvcHost.Open();

Well I don't have tremendous WCF background, but would this work?

m_SvcHost = new ServiceHost(this);
m_SvcHost.Description.Endpoints.Clear(); // <-- added

if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
{
    m_SvcHost.AddServiceEndpoint(typeof(IMyService),
        new BasicHttpBinding(),
        Config.ServiceEndpoint);
}

m_SvcHost.Open();
半葬歌 2024-08-24 14:00:42

通过结合 gWiz 和 Dylan 的答案,我想出了一种方法来做到这一点,尽管我还没有进行足够彻底的测试,无法知道这些更改是否破坏了任何其他功能。

基本上,我添加了这个类:

public class MobileMonitoringSvcHost : ServiceHost
{
    protected override void ApplyConfiguration()
    {
        // skip this line to not apply default config - unsure of other ramifications of doing this yet...
        base.ApplyConfiguration();

        base.Description.Endpoints.Clear();
    }

    public MobileMonitoringSvcHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses)
    {

    }
}

这会跳过 ServiceHost“ApplyConfiguration”调用,并且(目前可能没有必要,因为如果未加载配置,则不应有端点)清除端点。然后我执行以下操作:

m_SvcHost = new MySvcHost(this);


        if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
        {
            //m_SvcHost.Description.Endpoints.Clear();


            m_SvcHost.AddServiceEndpoint(typeof(IMobileMonitoringSvc),
                new BasicHttpBinding(),
                Config.ServiceEndpoint);
        }


        // open the svchost and allow incoming connections
        m_SvcHost.Open();

这确实会导致服务仅侦听外部配置的端点,而不是 app.config 配置的端点

谢谢!

By combining both gWiz and Dylan's answers I came up with a way to do this, though I haven't tested thoroughly enough to know if I have broken any other functionality with these changes.

Basically, I added this class:

public class MobileMonitoringSvcHost : ServiceHost
{
    protected override void ApplyConfiguration()
    {
        // skip this line to not apply default config - unsure of other ramifications of doing this yet...
        base.ApplyConfiguration();

        base.Description.Endpoints.Clear();
    }

    public MobileMonitoringSvcHost(object singletonInstance, params Uri[] baseAddresses) : base(singletonInstance, baseAddresses)
    {

    }
}

This skips the ServiceHost "ApplyConfiguration" call and (likely needlessly for now because if the config isn't loaded there should be no endpoints) clears the endpoints. Then I do the following:

m_SvcHost = new MySvcHost(this);


        if (Config.ServiceEndpoint != null && Config.ServiceEndpoint != String.Empty)
        {
            //m_SvcHost.Description.Endpoints.Clear();


            m_SvcHost.AddServiceEndpoint(typeof(IMobileMonitoringSvc),
                new BasicHttpBinding(),
                Config.ServiceEndpoint);
        }


        // open the svchost and allow incoming connections
        m_SvcHost.Open();

This does cause the service to only listen on the externally configured endpoint and not the app.config configured endpoint

Thanks!

我很OK 2024-08-24 14:00:42

我不相信你根本不需要配置部分——也就是说你可以用代码来完成这一切。如果您将这些内容留在 .config 中,那么它将与您在代码中编写的内容一起使用。

如果你想要其中之一,我认为你必须删除其中之一。

You don't have to have the configuration piece at all, I don't believe - i.e. you can do it all in code. If you leave the stuff in .config then it'll be used along with what you write in code.

If you want one or the other, I think you have to remove one or the other.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文