在IIS 7中是否存在用于NetTcp绑定的ASP样式路由表?

时间:2011-05-04 01:56:51

标签: wcf url-routing net.tcp

我正在努力将服务的绑定从Restful http更改为netTcp,用于IIS 7上托管的一组应用程序服务。restful配置使用路由表,并基于a动态创建端点命名约定和依赖注入。由于我们现在需要在事务块(DTS)中调用它们,因此我们将这些服务转换为Net Tcp绑定。

我希望能够通过使用的约定模型和依赖注入来保持路由,而不是拥有大量凌乱的.svc文件。我知道ASP路由表不适用于其他绑定。对替代品的任何建议?自定义HttpModule可以做到吗?

  • 将投票通过任何有用的信息或勾选答案或链接到答案。

谢谢, 亚伦

2 个答案:

答案 0 :(得分:4)

不,net.tcp绑定没有直接等效的ASP.NET RouteTable。并且自定义HttpModule不会有帮助,因为它只适用于HTTP;)

但是,您仍然可以做一些事情。首先,如果您不希望每个服务都有.SVC文件,您可以利用新的(WCF 4)基于配置的服务激活,它允许您在应用程序中声明所有WCF服务&# 39; s Web.config(在system.serviceModel中),如下所示:

<serviceHostingEnvironment>
  <serviceActivations>
    <add relativeAddress="Service1.svc" service="MyNamespace.MyService1"/>
    <add relativeAddress="Foo/Service2.svc" service="MyNamespace.MyService2"/>
    <add relativeAddress="Bar/a/Service3.svc" service="MyNamespace.MyService3" factory="System.ServiceModel.Activation.ServiceHostFactory"/>
  </serviceActivations>
</serviceHostingEnvironment>

注意:

  • @factory属性默认为ServiceHostFactory,即如果您正在使用其他工厂类型(例如WebServiceHostFactory或自定义工厂类型),则只需指定它
  • 主要的挑战是,@相关地址必须包含一个扩展!!
  • 扩展必须在system.web / compilation / buildProviders中声明,并且在那里指定的类型必须具有[ServiceActivationBuildProvider]属性(System.ServiceModel.Activation)
  • 这意味着实际上您最终会使用.svc扩展名,因为默认情况下已在根Web.config中声明了该扩展名。

但是,这种方法至少允许您在一个地方定义所有服务(而不是多个.svc 文件) - 在这方面,它与{{1 }}

现在,如果你被.svc扩展所困扰,你甚至可以更进一步。 WCF4中的另一个新项目是路由服务(请参阅http://msdn.microsoft.com/en-us/library/ee517423.aspx),它是一种通用WCF服务,它接收消息以便根据各种标准将其转发到其他WCF服务(如SOAP标头) ,消息内容,端点地址等。)。

使用路由服务,您可以定义各种EndpointAddress过滤器(例如,net.tcp:// {routing-service-base} / service1,net.tcp:// {routing-service-base} / service2等。) - 它让你更接近ASP.NET路由。

但是,如果您在IIS中托管路由服务本身,显然,那个仍然会以RouteTable基地址结束!

如何绕过最后一个限制(例如,如何在一个漂亮的URI上托管路由服务本身,如 net.tcp:// servername / XYZServices )的唯一方法是例如,在Windows服务中自行托管路由服务 - 这使您可以完全控制其基址。然后,您可以继续在IIS中托管实际的目标服务 - 扩展名为.svc - 并且您的路由服务将转换&#34; nice&#34;公共URI进入IIS .svc的。

但是,放弃IIS / AppFabric托管只是为了获得不错的URI,这是一个艰难的决定。我可能不会这样做。

希望你至少可以使用其中一些:)

答案 1 :(得分:2)

这个问题答案已有近一年的历史了。不过,我遇到了同样的问题。

简短的回答是你已经发现的。它不起作用。然而,这从未阻止我们。稍后进行的一些研究以及对激活机制的一些“潜入”提供了以下工作解决方案:

public class CustomRouting
{
    public static void Route(string routePrefix, ServiceHostFactoryBase serviceHostFactory, Type serviceType)
    {
        var serviceHostingEnvironment = new StaticReflectionWrapper(typeof (ServiceHostingEnvironment));
        serviceHostingEnvironment.StaticMethod("EnsureInitialized");
        var hostManager = serviceHostingEnvironment.GetStaticField("hostingManager");

        var hostingManager = new InstanceReflectionWrapper(hostManager);
        var normalizedAddress = hostingManager.Method<string>("NormalizedRelativeAddress", routePrefix);
        var serviceActivation = new KeyValuePair<string, string>(normalizedAddress, string.Format("{0}|{1}|{2}", normalizedAddress, serviceHostFactory.GetType().FullName, serviceType.FullName));
        hostingManager.GetField<Hashtable>("serviceActivations").Add(serviceActivation.Key, serviceActivation.Value);

        var tD = StaticReflectionWrapper.Resolve(typeof (ServiceHostingEnvironment).Assembly, "TD");
        if (tD.StaticMethod<bool>("CBAEntryReadIsEnabled"))
        {
            tD.StaticMethod("CBAEntryRead", routePrefix, serviceActivation.Key);
        }

        ServiceHostingEnvironment.EnsureServiceAvailable(serviceActivation.Key);
    }
}

辅助类StaticReflectionWrapper和InstanceReflectionWrapper只是辅助类,以保持反射的可读性。

您使用Route方法如下:

var fact = new CustomServiceHostFactory();
CustomRouting.Route("DynamicServices/" + service.GetType().Name + ".svc", fact, service.GetType());

服务变量是ServiceContract的实现。

自行承担使用此风险,因为这实际上会降低到我们不应该来的地区。然而,它有效。

希望这会缩短很多人的搜索时间,并且会关闭。