WCF 肥皂 +没有 .svc 的 REST/Json 服务 - 我的服务工厂数量是否是两倍?

发布于 2025-01-06 11:44:15 字数 3648 浏览 2 评论 0原文

好的,所以我想要将单个服务公开为 SOAP 以及 REST (Json) 端点。由于它脱离了“WCF 服务应用程序”模板,因此我有一个 web.config,并将以下内容添加到...

web.config

<configuration>
  ...
  <system.serviceModel>
    <services>
        <service name="MySvcClass">
            <endpoint address="" binding="webHttpBinding" contract="MySvcInterfaceClass" behaviorConfiguration="restBehavior" />
            <endpoint address="soap" binding="basicHttpBinding" contract="MySvcInterfaceClass" />
            <endpoint address="mex"  binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="restBehavior">
                <webHttp helpEnabled="true"/>
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
  </system.serviceModel>
  ...
</configuration>

假设 MySvcClass 类在 \MySvcClass.svc 中实现,则上面公开了...

原始端点

localhost\MySvcClass.svc\(其余端点)

localhost\MySvcClass.svc\mex(元数据交换到使用下面的 SOAP 端点)

localhost\MySvcClass.svc\soap (soap 端点)

到目前为止,一切都很好(我认为!)。

然后我想摆脱上面路径中看到的丑陋的“.svc”。所以我遵循了这个 MSDN 博客文章 并在我的...

global.asax

void Application_Start(object sender, EventArgs e)
{       
    RouteTable.Routes.Add(new ServiceRoute("MySvcClass", new WebServiceHostFactory(), typeof(MySvcClass)));
}

有趣的是,当我在 Application_Start 中放置断点时,VS2010 不会命中这个特定的断点 - 即使我停止->开始调试或停止->启动 IIS 应用程序池。奇怪!无论如何,回到正题,我现在可以访问上面列出的端点和

Cleaner Endpoints

localhost\MySvcClass\ (其余端点)

localhost\MySvcClass\mex 的 服务(使用下面的 SOAP 端点的元数据交换)

localhost\MySvcClass\soap(soap 端点)

问题

  1. 我有两个服务工厂吗?一个来自 web.config,另一个来自 global.asax?如果是,我怎样才能避免它,同时仍然拥有干净的 URL(没有 .svc)。我真的不需要路径中带有 .svc 的文件...
  2. 我不喜欢混乱的 web.configs,所以有什么方法可以将上述 SOAP 和 REST 配置从 XML (web.config) 移动到代码中(例如全局.asax?)?我知道如何移动 REST only 端点 - 在 web.config 中删除,保留 global.asax 原样。然而,这样做会杀死 SOAP 端点。

[更新] 我也尝试过 URL 重写,但这会杀死 SOAP 端点,同时保持 REST 端点处于活动状态。我所做的是:在 web.config 中使用 MS 的 URL Rewrite 2.0 模块,

<system.webServer> 
  <modules runAllManagedModulesForAllRequests="true"/> 
  <rewrite> 
    <rules> 
      <rule name="RemoveSvcExt" stopProcessing="true"> 
        <match url="^MySvcClass(.*)$" /> 
        <action type="Rewrite" url="MySvcClass.svc{R:1}" /> 
      </rule> 
    </rules> 
  </rewrite> 
</system.webServer> 

但是,这会使 Web 应用程序处于某种不一致的状态,因为有些部分仍然坚持 .svc URL。例如:服务端点处的 HTML 帮助页面显示 svcutil.exe http://localhost/MySvcClass.svc?wsdl 甚至 WSDL 位于 http://localhost/MySvcClass 的干净位置?wsdl 引用其中的 http://localhost/MySvcClass.svc - 这有效地杀死了 SOAP 端点。

这就是为什么我认为(0.02 美元)重写只是一个拼凑。叹息,此时我正在与框架斗争以完成工作。而且感觉很浪费时间......

Ok, so I wanted to have a single service exposed as a SOAP as well as REST (Json) end point. Since it's off the "WCF Service Application" template, I have a web.config and I added the following into the ...

web.config

<configuration>
  ...
  <system.serviceModel>
    <services>
        <service name="MySvcClass">
            <endpoint address="" binding="webHttpBinding" contract="MySvcInterfaceClass" behaviorConfiguration="restBehavior" />
            <endpoint address="soap" binding="basicHttpBinding" contract="MySvcInterfaceClass" />
            <endpoint address="mex"  binding="mexHttpBinding" contract="IMetadataExchange" />
        </service>
    </services>
    <behaviors>
        <serviceBehaviors>
            <behavior>
                <serviceMetadata httpGetEnabled="true"/>
                <serviceDebug includeExceptionDetailInFaults="false"/>
            </behavior>
        </serviceBehaviors>
        <endpointBehaviors>
            <behavior name="restBehavior">
                <webHttp helpEnabled="true"/>
            </behavior>
        </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true"/>
  </system.serviceModel>
  ...
</configuration>

Assuming the MySvcClass class is implemented within \MySvcClass.svc, the above exposes ...

Original Endpoints

localhost\MySvcClass.svc\ (rest endpoint)

localhost\MySvcClass.svc\mex (Metadata Exchange to the use the SOAP end point below)

localhost\MySvcClass.svc\soap (soap endpoint)

So far, so good (I think!).

Then I wanted to get rid of the ugly ".svc" seen in the paths above. So I followed this MSDN blog post and had this in my ...

global.asax

void Application_Start(object sender, EventArgs e)
{       
    RouteTable.Routes.Add(new ServiceRoute("MySvcClass", new WebServiceHostFactory(), typeof(MySvcClass)));
}

Interestingly, when I put a breakpoint inside Application_Start, VS2010 doesn't hit this particular breakpoint - even when I stop->start debugging or stop->start the IIS application pool. Bizarre! Anyway, back to the point, I can now access the services the above listed endpoints AND

Cleaner Endpoints

localhost\MySvcClass\ (rest endpoint)

localhost\MySvcClass\mex (Metadata Exchange to the use the SOAP end point below)

localhost\MySvcClass\soap (soap endpoint)

Questions

  1. Am I having TWO service factories? One from the web.config and the other from the global.asax? If yes, how can I avoid it while still having clean URLs (without .svc). I don't really need the ones with .svc in the path ...
  2. I dislike cluttered web.configs, so is there any way I can move the above SOAP and REST configuration from the XML (web.config) into code (eg global.asax?) ? I know how to move the REST only end point - wipe out in the web.config, leave global.asax as is. However doing that kills the SOAP endpoint.

[Update]
I had tried URL rewrites too but this killed the SOAP endpoint while keeping the REST endpoint alive. Wht I did was : Used MS's URL Rewrite 2.0 module with this in the web.config

<system.webServer> 
  <modules runAllManagedModulesForAllRequests="true"/> 
  <rewrite> 
    <rules> 
      <rule name="RemoveSvcExt" stopProcessing="true"> 
        <match url="^MySvcClass(.*)$" /> 
        <action type="Rewrite" url="MySvcClass.svc{R:1}" /> 
      </rule> 
    </rules> 
  </rewrite> 
</system.webServer> 

However, this leaves the web app in some inconsistent state because there are some parts which still stick to the .svc URLs. eg: the HTML help page at the service endpoint shows svcutil.exe http://localhost/MySvcClass.svc?wsdl Even the WSDL at the clean location at http://localhost/MySvcClass?wsdl makes references to http://localhost/MySvcClass.svc inside it - this effectively kills the SOAP endpoint.

That's why I think ($0.02) the rewrite is just a kludge. Sigh, at this point I'm fighting with the framework to get stuff done. And it feels such a time burner ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不爱素颜 2025-01-13 11:44:15

对于没有 .svc 的服务,在 wcf 中搜索无文件激活
http://www.a2zdotnet.com/View.aspx?Id=188

For services without .svc search for file less activations in wcf
http://www.a2zdotnet.com/View.aspx?Id=188

心意如水 2025-01-13 11:44:15

我有一个 REST 项目,它同时公开了 REST 和 SOAP 服务。现在,我放置了一个 .svc 文件,供某些客户端访问 SOAP 服务。

下面的屏幕截图给出了我的项目的文件夹结构、global.asax中的路由配置、访问Rest服务和访问.svc文件(SOAP服务)的输出。要删除 .svc 扩展名,请使用 URL 重写模块。

sample snapshot

请找到我的 web.Config(我的应用程序托管在 IIS 上):

web.config

请找到实现我的接口 ISampleService 的类:

I have a REST project that as both REST and SOAP service being exposed. Now I placed an .svc file for the SOAP service to be accessed by some clients.

The below screenshot gives the folder structure of my project, the route configuration in global.asax, Output accessing the Rest Service and accessing the .svc file (SOAP service). To remove the .svc extension use the URL rewrite module.

sample screenshot

Please find my web.Config (My application is hosted on IIS):

web.config

Please find my class that implements my interface ISampleService:

class

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文