在运行时停止/启动WCF MEX服务

时间:2009-02-13 19:17:33

标签: c# c#-3.0 wcf

是否可以/如何在运行时停止并启动自托管WCF服务的HTTP MEX侦听器而不影响主WCF服务?

(请不要问我为什么要这样做。这是一个克服其他人施加的人为限制的黑客攻击。)

1 个答案:

答案 0 :(得分:3)

***** [重新测试和代码清理后重新添加了这个答案]这是我添加到基于WCF的通用服务开发框架的实际代码,并且已经过全面测试。*****

假设您从ServiceHost ...

启用MEX开始
  

以下解决方案已写入   ServiceHost子类的术语   实现的(WCFServiceHost<T>)   一个特殊的界面(IWCFState)   存储MEX的实例   EndpointDispatcher上课。

首先,添加这些名称空间......

using System.ServiceModel;
using System.ServiceModel.Dispatcher;

其次,定义IWCFState接口...

public interface IWCFState
{
    EndpointDispatcher MexEndpointDispatcher
    {
        get;
        set;
    }
}

第三,为某些ServiceHost扩展方法创建一个静态类(我们将在下面填写)...

public static class WCFExtensions
{
    public static void RemoveMexEndpointDispatcher(this ServiceHost host){}

    public static void AddMexEndpointDispatcher(this ServiceHost host){}
}

现在让我们填写扩展方法......

在运行时{/ 1}}停止MEX

ServiceHost

然后这样称呼它......

public static void RemoveMexEndpointDispatcher(this ServiceHost host)
{
    // In the simple example, we only define one MEX endpoint for
    // one transport protocol
    var queryMexChannelDisps = 
            host.ChannelDispatchers.Where(
                disp => (((ChannelDispatcher)disp).Endpoints[0].ContractName
                                            == "IMetadataExchange"));
    var channelDisp = (ChannelDispatcher)queryMexChannelDisps.First();

    // Save the MEX EndpointDispatcher
    ((IWCFState)host).MexEndpointDispatcher = channelDisp.Endpoints[0];

    channelDisp.Endpoints.Remove(channelDisp.Endpoints[0]);
}

在运行时{/ 1}}上(再次)启动MEX

// WCFServiceHost<T> inherits from ServiceHost and T is the Service Type,
// with the new() condition for the generic type T.  It encapsulates 
// the creation of the Service Type that is passed into the base class 
// constructor.
Uri baseAddress = new Uri("someValidURI");
WCFServiceHost<T> serviceImplementation = new WCFServiceHost<T>(baseAddress);

// We must open the ServiceHost first...
serviceImplementation.Open();

// Let's turn MEX off by default.
serviceImplementation.RemoveMexEndpointDispatcher();

然后这样称呼它......

ServiceHost

摘要

此设计允许您使用某些消息传递方法向服务本身或托管服务的代码发送命令,并使其执行MEX public static void AddMexEndpointDispatcher(this ServiceHost host) { var queryMexChannelDisps = host.ChannelDispatchers.Where( disp => (((ChannelDispatcher)disp).Endpoints.Count == 0)); var channelDisp = (ChannelDispatcher)queryMexChannelDisps.First(); // Add the MEX EndpointDispatcher channelDisp.Endpoints.Add(((IWCFState)host).MexEndpointDispatcher); } 的启用或禁用,从而有效地关闭MEX对于serviceImplementation.AddMexEndpointDispatcher();

注意:此设计假设代码在启动时将支持MEX,但随后它将使用配置设置来确定在EndpointDispatcher上调用ServiceHost后服务是否将禁用MEX。如果您在Open()打开之前尝试调用任一扩展方法,则会抛出此代码。

注意事项:我可能会创建一个特殊的服务实例,其管理操作在启动时不支持MEX,并将其建立为服务控制通道。

资源

我发现以下两个资源在解决这个问题时是不可或缺的: