ServiceRoute + WebServiceHostFactory 杀死 WSDL 生成?如何使用 ?wsdl 创建无扩展的 WCF 服务 [英] ServiceRoute + WebServiceHostFactory kills WSDL generation? How to create extensionless WCF service with ?wsdl

查看:20
本文介绍了ServiceRoute + WebServiceHostFactory 杀死 WSDL 生成?如何使用 ?wsdl 创建无扩展的 WCF 服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用无扩展/无 .svc 的 WCF 服务.其他人可以确认或否认我遇到的问题吗?

我在代码中使用路由,并在 global.asax.cs 的 Application_Start 中执行此操作:

RouteTable.Routes.Add(new ServiceRoute("Data", new WebServiceHostFactory(), typeof(DataDips)));

我已经在 IIS 6 和 IIS 7.5 中进行了测试,我可以很好地使用该服务(即我的无扩展名通配符映射处理程序配置正确指向 ASP.NET).然而,元数据生成完全搞砸了.我可以使用 WCF 测试客户端(我假设是 svcutil.exe)访问我的/mex 端点——但是您通常使用 .svc 获得的 ?wsdl 生成是吐司.我无法使用浏览器访问它(获得 400 个错误的请求),我无法使用 wsdl.exe 等访问它.在 web.config 中正确配置了元数据生成.

这当然是一个问题,因为服务公开为 basicHttpBinding 以便旧式 ASMX 客户端可以访问它.但是当然,如​​果没有 WSDL 描述,客户端是无法生成代理的.

如果我像这样在配置中使用 serviceActivation 路由,而不是在代码中注册路由:

<服务激活><add relativeAddress="Data.svc" service="DataDips"/></serviceActivations></serviceHostingEnvironment>

然后瞧...它起作用了.

但是我没有一个干净的无扩展名 url.如果我将relativeAddress 从Data.svc 更改为Data,则会出现配置异常,因为config 不支持此异常.(必须使用注册到 WCF 的扩展).

我还尝试将此代码与上述配置结合使用:

RouteTable.Routes.MapPageRoute("","Data/{*data}","~/Data.svc/{*data}",false);

我的想法是我可以将无扩展名的 url 指向配置的 .svc url.这不起作用 -/Data.svc 继续工作,但/Data 返回 404.

如果在这样的配置中使用 urlMappings 并与上面的 serviceActivation 结合使用,我确实找到了一种解决方法:

<add url="~/Data" mappingUrl="Data.svc"/></urlMappings>

这个问题是双重的——1. 看起来很复杂2.在生成的WSDL中,操作端点仍然引用Data.svc/,而不是Data/——因此对Data.svc实际存在/响应的依赖.

这不是我真正想要的,即使它有点/可以解决问题.

是否有一种正确的方法可以让无扩展的 WCF 服务 url 正确生成 WSDL?

解决方案

哇,我是不是觉得自己很笨.

我应该使用 ServiceHostFactory 而不是 WebServiceHostFactory 来托管我的服务.

一旦我从配置中移回代码...并切换到这行代码:

RouteTable.Routes.Add(new ServiceRoute("Data", new ServiceHostFactory(), typeof(DataDips)));

我从事提供 WSDL 和帮助页面的无扩展 URL 的业务.

太糟糕了,我在这上面浪费了太多时间.我使用 WebServiceHostFactory 是一个意外,但 MSDN 的工厂页面上没有关于减少功能的免责声明.(我认为删除 WSDL 是有道理的,但删除帮助页面没有意义,因为如果存在具有该名称的 REST 操作,它们可以简单地在配置中提供一个属性来重命名帮助"页面......叹气).

WebServiceHost 文档中有一个注释http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webservicehost.aspx

I'm trying to use extension-less / .svc-less WCF services. Can anyone else confirm or deny the issue I'm experiencing?

I use routing in code, and do this in Application_Start of global.asax.cs:

RouteTable.Routes.Add(new ServiceRoute("Data", new WebServiceHostFactory(), typeof(DataDips)));

I have tested in both IIS 6 and IIS 7.5 and I can use the service just fine (ie my extension-less wildcard mapping handler config is correctly pointed at ASP.NET). However, metadata generation is totally screwed up. I can hit my /mex endpoint with the WCF Test Client (and I presume svcutil.exe) -- but the ?wsdl generation you typically get with .svc is toast. I can't hit it with a browser (get 400 bad request), I can't hit it with wsdl.exe, etc. Metadata generation is configured correctly in web.config.

This is a problem of course, because the service is exposed as basicHttpBinding so that an old style ASMX client can get to it. But of course, the client can't generate the proxy without a WSDL description.

If I instead use serviceActivation routing in config like this, rather than registering a route in code:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true">
  <serviceActivations>
    <add relativeAddress="Data.svc" service="DataDips" />
  </serviceActivations>
</serviceHostingEnvironment>

Then voila... it works.

But then I don't have a clean extensionless url. If I change relativeAddress from Data.svc to Data, then I get a configuration exception as this is not supported by config. (Must use an extension registered to WCF).

I've also attempted to use this code in conjunction with the above config:

RouteTable.Routes.MapPageRoute("","Data/{*data}","~/Data.svc/{*data}",false);

My thinking is that I can just point the extensionless url at the configured .svc url. This doesn't work -- the /Data.svc continues to work, but /Data returns a 404.

I did find a work-around if using urlMappings in config like this, in conjunction with serviceActivation above:

<urlMappings>
   <add url="~/Data" mappedUrl="Data.svc"/>
</urlMappings>

The problem with this is twofold - 1. It seems convoluted 2. In the generated WSDL, the operation endpoints still refer to Data.svc/, rather than Data/ -- therefore theres dependency on Data.svc actually existing / responding.

This is not really what I want, even if it kinda / sorta solves the problem.

Is there a proper way of getting extension-less WCF service urls to generate WSDL correctly?

解决方案

Wow, do I feel dumb.

I should have been hosting my service with ServiceHostFactory, NOT WebServiceHostFactory.

As soon as I moved back to code from config... and swapped to this line of code:

RouteTable.Routes.Add(new ServiceRoute("Data", new ServiceHostFactory(), typeof(DataDips)));

I was in business with an extensionless URL serving up WSDL and help pages.

It's too bad I wasted so much time on this. It was an accident that I was using WebServiceHostFactory, but there's no disclaimer on the factory page in MSDN about the reduced functionality. (I would argue that removing WSDL makes sense, but removing the Help pages does not as they could simply provide an attribute in config to rename the 'Help' page should there be a REST operation with that name... sigh).

There is a note in the WebServiceHost docs http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webservicehost.aspx

这篇关于ServiceRoute + WebServiceHostFactory 杀死 WSDL 生成?如何使用 ?wsdl 创建无扩展的 WCF 服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆