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

4
我正在尝试允许用户配置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上。我找不到任何方法来删除原始终结点或创建没有定义终结点的服务。
从配置应用程序中写入app.config不是一个选项 - 我需要通过编程从单独的XML配置文件中获取配置值...
有什么想法吗?
编辑:该服务作为Windows服务运行,并公开HTTP端点,它不作为托管在IIS中的Web服务运行 - 如果改变了这些内容,请告知。
4个回答

2

Justin,

这个代码能帮到你吗?这段代码可以让你响应在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" %>

我最初没有提到该服务是一个Windows服务,并且没有托管在IIS中 - 我尝试过这样做,只发现CreateServiceHost对于Windows服务不可用。 - JustinD

2

我对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();

它确实清除了端点,然后只添加了我想要的一个,但是服务仍然在两个端口上响应,即使在端点集合中只列出了外部配置的端点。 - JustinD

1
通过结合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配置的端点

谢谢!


0

你不必拥有配置部分,我认为 - 也就是说,你可以全部在代码中完成。如果你将东西留在 .config 中,那么它将与你在代码中编写的内容一起使用。

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


我的问题是我希望服务仅响应通过配置应用程序配置的IP/端口,而不是在app.config中列出的URI...但是我无法删除app.config中的终结点配置,否则就无法实例化新的ServiceHost条目(因为此时没有配置终结点)。 - JustinD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接