是否可以/如何在运行时停止并启动自托管WCF服务的HTTP MEX侦听器而不影响主WCF服务?
(请不要问我为什么要这样做。这是一个克服其他人施加的人为限制的黑客攻击。)
答案 0 :(得分:3)
***** [重新测试和代码清理后重新添加了这个答案]这是我添加到基于WCF的通用服务开发框架的实际代码,并且已经过全面测试。*****
假设您从ServiceHost
...
以下解决方案已写入
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){}
}
现在让我们填写扩展方法......
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]);
}
// 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,并将其建立为服务控制通道。
我发现以下两个资源在解决这个问题时是不可或缺的:
.NET Reflector:类浏览器,分析器&amp;用于检查System.ServiceModel.dll 等程序集的反编译器:http://www.red-gate.com/products/reflector/
扩展调度程序(MSDN):提供WCF服务的类组合的精彩高级图表:http://msdn.microsoft.com/en-us/library/ms734665.aspx