结合 WCF SOAP 和 REST

发布于 2025-01-06 12:32:15 字数 4957 浏览 0 评论 0 原文

REST项目工作正常,可以通过以下地址访问:

http ://localhost:8525/Device/Login?deviceID=testid&password=a&ser​​ialNum=testserial

我也有 WCF SOAP 项目在我的 REST 项目中,这两个项目位于不同的文件夹“SOAP”和“REST”中。

我的问题是,在输入此代码后:

private void RegisterRoutes()
{
    RouteTable.Routes.Add(new ServiceRoute("Device", new WebServiceHostFactory(), typeof(Rest.DeviceComponent)));              
}  

我现在无法访问之前可以通过以下地址访问的 SOAP 服务:

http://localhost:8525/DeviceComponent.svc(使用 WCFTest 客户端)

这是 WebConfig

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
    <handlers>
      <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd"/>
    </handlers>
  </system.webServer>
</configuration>

和 Global.asax.cs

private void RegisterRoutes()
{
    RouteTable.Routes.Add(new ServiceRoute("Device", new WebServiceHostFactory(), typeof(Rest.DeviceComponent)));
}    

SOAP 示例合约

namespace TSDEVICE.SoapSVC.Interface
{
    [ServiceContract]
    public interface IDeviceComponent
    {
        [OperationContract]
        Session Login(string deviceID, string password, string serialNum, string ip);
        [OperationContract]
        bool Logout(DeviceSession session);
        [OperationContract]
        bool IsLatestVersion(DeviceSession session, int version);
        [OperationContract]
        byte[] DownloadLatest(DeviceSession details);
        [OperationContract]
        DateTime GetServerTime(DeviceSession session, long branchID);
        [OperationContract]
        bool AddDevice(UserSession session, Device deviceitem);
        [OperationContract]
        bool RemoveDevice(UserSession session, long deviceID);
    }
}  

内部以及 REST 部分:

namespace TSDEVICE.Rest
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class DeviceComponent
    {
        [WebInvoke(UriTemplate = "Login?deviceID={deviceID}&password={password}&serialNum={serialNum}", Method = "POST")]
        [OperationContract]
        public TMODELDEVICE.Entities.Session Login(string deviceID, string password, string serialNum)
        {
            string ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            TMODELDEVICE.Logic.DeviceComponent restDC = new TMODELDEVICE.Logic.DeviceComponent();
            return restDC.Login(deviceID, password, serialNum, ip);
        }

        public string Sample()
        {
            return "Hello";
        }
    }
}  

我必须访问 SOAP 和 REST ,我怎样才能做到这一点?多谢!

编辑

当我尝试将 .svc 文件“设置为起始页”时,出现此错误:

Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.  

编辑 2

现在我发现了真正的问题。

当 web.config 中的 ASP.NET 兼容模式 == true 时,SOAP 无法工作,而 REST 需要它。我该怎么办?谢谢

The REST project works fine, this can be accessed through this address:

http://localhost:8525/Device/Login?deviceID=testid&password=a&serialNum=testserial

I also have WCF SOAP project in my REST project, these two projects are separated in different folders, "SOAP" and "REST".

My problem is that, after I put this code:

private void RegisterRoutes()
{
    RouteTable.Routes.Add(new ServiceRoute("Device", new WebServiceHostFactory(), typeof(Rest.DeviceComponent)));              
}  

I can't access now the SOAP service which I was able to access before through this address:

http://localhost:8525/DeviceComponent.svc (using WCFTest Client)

Here is the WebConfig

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
          <serviceMetadata httpGetEnabled="true"/>
          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
          <serviceDebug includeExceptionDetailInFaults="true"/>
        </behavior>
      </serviceBehaviors>
    </behaviors>
    <serviceHostingEnvironment multipleSiteBindingsEnabled="true" aspNetCompatibilityEnabled="true" />
    <standardEndpoints>
      <webHttpEndpoint>
        <!-- 
            Configure the WCF REST service base address via the global.asax.cs file and the default endpoint 
            via the attributes on the <standardEndpoint> element below
        -->
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"/>
      </webHttpEndpoint>
    </standardEndpoints>
  </system.serviceModel>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
      <add name="UrlRoutingModule" type="System.Web.Routing.UrlRoutingModule, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </modules>
    <handlers>
      <add name="UrlRoutingHandler" preCondition="integratedMode" verb="*" path="UrlRouting.axd"/>
    </handlers>
  </system.webServer>
</configuration>

And inside Global.asax.cs

private void RegisterRoutes()
{
    RouteTable.Routes.Add(new ServiceRoute("Device", new WebServiceHostFactory(), typeof(Rest.DeviceComponent)));
}    

SOAP sample contract

namespace TSDEVICE.SoapSVC.Interface
{
    [ServiceContract]
    public interface IDeviceComponent
    {
        [OperationContract]
        Session Login(string deviceID, string password, string serialNum, string ip);
        [OperationContract]
        bool Logout(DeviceSession session);
        [OperationContract]
        bool IsLatestVersion(DeviceSession session, int version);
        [OperationContract]
        byte[] DownloadLatest(DeviceSession details);
        [OperationContract]
        DateTime GetServerTime(DeviceSession session, long branchID);
        [OperationContract]
        bool AddDevice(UserSession session, Device deviceitem);
        [OperationContract]
        bool RemoveDevice(UserSession session, long deviceID);
    }
}  

And the REST part:

namespace TSDEVICE.Rest
{
    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class DeviceComponent
    {
        [WebInvoke(UriTemplate = "Login?deviceID={deviceID}&password={password}&serialNum={serialNum}", Method = "POST")]
        [OperationContract]
        public TMODELDEVICE.Entities.Session Login(string deviceID, string password, string serialNum)
        {
            string ip = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
            TMODELDEVICE.Logic.DeviceComponent restDC = new TMODELDEVICE.Logic.DeviceComponent();
            return restDC.Login(deviceID, password, serialNum, ip);
        }

        public string Sample()
        {
            return "Hello";
        }
    }
}  

I have to access SOAP and REST, how can I do that? Thanks a lot!

EDIT

When I try to "Set as Start page" the .svc file, I get this error:

Failed to add a service. Service metadata may not be accessible. Make sure your service is running and exposing metadata.  

EDIT 2

Now I found out the real problem.

When ASP.NET compatibility mode in the web.config == true, SOAP fail to work, while REST requires it. What should I do with this? Thanks

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

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

发布评论

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

评论(2

千秋岁 2025-01-13 12:32:15

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

下面的屏幕截图给出了我的项目的文件夹结构,global.asax中的路由配置,访问Rest Service和访问.svc文件(SOAP服务)的输出

示例屏幕截图

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

web.config

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

class

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)

sample screenshot

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

web.config

Please find my class that implements my interface ISampleService:

class

一场信仰旅途 2025-01-13 12:32:15

虽然我很欣赏上面列出的解决方案 - 我发现如果您不过度思考问题并遵循 KISS 原则,管理/部署会容易得多。

服务合约:IService.cs

namespace DontTazeMe.Bro
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebGet]
        List<GeoMapData> GetToTheChopper();
    }
}

实现:Service.cs

namespace DontTazeMe.Bro
{
    public class WSDLService : IService
    {
        public List<GeoMapData> GetToTheChopper()
        {
            return ItsNotEasyBeingChessy.Instance.GetToTheChopperGeoData();
        }
    }

    public class RESTService : WSDLService
    {
        // Let's move along folks, nothing to see here...
        // Seriously though - there is no need to duplicate the effort made in
        // the WSDLService class as it can be inherited and by proxy implementing 
        // the appropriate contract
    }
}

配置

<system.serviceModel>
    <services>
      <!-- SOAP Service -->
      <service name="DontTazeMe.Bro.WSDLService">
        <endpoint address="" binding="basicHttpBinding" contract="DontTazeMe.Bro.IService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/DontTazeMe.Bro/Service/" />
          </baseAddresses>
        </host>
      </service>
      <service name="DontTazeMe.Bro.RESTService">
        <endpoint address="" binding="webHttpBinding" contract="DontTazeMe.Bro.IService" behaviorConfiguration="Restful" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/DontTazeMe.Bro/Rest/Service/" />
          </baseAddresses>
        </host>
      </service>
      <behaviors>
      <endpointBehaviors>
        <behavior name="Restful">
          <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

此方法有效很好,不用被配置冲昏头脑

While I appreciate the solutions listed above - I have a found it is far easier to manage/deploy if you don't over think the problem and follow a KISS principle.

Service Contract: IService.cs

namespace DontTazeMe.Bro
{
    [ServiceContract]
    public interface IService
    {
        [OperationContract]
        [WebGet]
        List<GeoMapData> GetToTheChopper();
    }
}

Implementation: Service.cs

namespace DontTazeMe.Bro
{
    public class WSDLService : IService
    {
        public List<GeoMapData> GetToTheChopper()
        {
            return ItsNotEasyBeingChessy.Instance.GetToTheChopperGeoData();
        }
    }

    public class RESTService : WSDLService
    {
        // Let's move along folks, nothing to see here...
        // Seriously though - there is no need to duplicate the effort made in
        // the WSDLService class as it can be inherited and by proxy implementing 
        // the appropriate contract
    }
}

Configuration

<system.serviceModel>
    <services>
      <!-- SOAP Service -->
      <service name="DontTazeMe.Bro.WSDLService">
        <endpoint address="" binding="basicHttpBinding" contract="DontTazeMe.Bro.IService">
          <identity>
            <dns value="localhost" />
          </identity>
        </endpoint>
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/DontTazeMe.Bro/Service/" />
          </baseAddresses>
        </host>
      </service>
      <service name="DontTazeMe.Bro.RESTService">
        <endpoint address="" binding="webHttpBinding" contract="DontTazeMe.Bro.IService" behaviorConfiguration="Restful" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:8733/DontTazeMe.Bro/Rest/Service/" />
          </baseAddresses>
        </host>
      </service>
      <behaviors>
      <endpointBehaviors>
        <behavior name="Restful">
          <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" />
        </behavior>
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

This method works just fine without getting carried away with configuration

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