WCF 서비스의 REST / SOAP 엔드 포인트


425

WCF 서비스가 있으며 RESTfull 서비스와 SOAP 서비스로 노출하고 싶습니다. 아무도 전에 이런 짓을 한 적이 있습니까?


좋은 질문과 좋은 답변.
chandra rv

답변:


584

두 개의 다른 엔드 포인트에서 서비스를 노출 할 수 있습니다. SOAP 하나는 SOAP를 지원하는 바인딩 (예 : basicHttpBinding)을 사용할 수 있고, RESTful 하나는 webHttpBinding을 사용할 수 있습니다. REST 서비스가 JSON에 있다고 가정합니다.이 경우 다음 동작 구성으로 두 개의 엔드 포인트를 구성해야합니다.

<endpointBehaviors>
  <behavior name="jsonBehavior">
    <enableWebScript/>
  </behavior>
</endpointBehaviors>

시나리오에서 엔드 포인트 구성의 예는 다음과 같습니다.

<services>
  <service name="TestService">
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="json" binding="webHttpBinding"  behaviorConfiguration="jsonBehavior" contract="ITestService"/>
  </service>
</services>

따라서 서비스는

운영 계약에 [WebGet]을 적용하여 RESTful하게하십시오. 예 :

public interface ITestService
{
   [OperationContract]
   [WebGet]
   string HelloWorld(string text)
}

REST 서비스가 JSON에없는 경우 조작 매개 변수는 복합 유형을 포함 할 수 없습니다.

SOAP 및 RESTful POX (XML) 관련 게시물에 회신

반환 형식으로 사용되는 일반 XML은 SOAP 및 XML 모두에서 작동하는 예제입니다.

[ServiceContract(Namespace = "http://test")]
public interface ITestService
{
    [OperationContract]
    [WebGet(UriTemplate = "accounts/{id}")]
    Account[] GetAccount(string id);
}

REST Plain Old XML에 대한 POX 동작

<behavior name="poxBehavior">
  <webHttp/>
</behavior>

엔드 포인트

<services>
  <service name="TestService">
    <endpoint address="soap" binding="basicHttpBinding" contract="ITestService"/>
    <endpoint address="xml" binding="webHttpBinding"  behaviorConfiguration="poxBehavior" contract="ITestService"/>
  </service>
</services>

서비스는 다음에서 가능합니다

REST 요청 은 브라우저에서 시도하십시오.

http://www.example.com/xml/accounts/A123

서비스 참조를 추가 한 후 SOAP 서비스에 대한 SOAP 요청 클라이언트 엔드 포인트 구성

  <client>
    <endpoint address="http://www.example.com/soap" binding="basicHttpBinding"
      contract="ITestService" name="BasicHttpBinding_ITestService" />
  </client>

C #에서

TestServiceClient client = new TestServiceClient();
client.GetAccount("A123");

이를 수행하는 다른 방법은 서로 다른 두 개의 서비스 계약과 각각 특정 구성을 갖는 계약을 노출시키는 것입니다. 이로 인해 코드 수준에서 일부 복제본이 생성 될 수 있지만 하루가 끝날 때 작동하게 만들 수 있습니다.


11
someserver / myvirtualdir / service.svc 와 같은 가상 디렉터리의 IIS에서 .svc를 호스팅하면 어떻게 됩니까? 어떻게 액세스해야합니까?
Sunny Milenov

한 단계 더 나아가 JSON 주소의 HTTPS에 바인딩을 추가하고 싶습니다. 어떻게합니까? stackoverflow.com/questions/18213472/…
Steve

내 서비스 인터페이스를 참조하려고 할 때 계약 IEvents가 유효하지 않다고 말하는 것입니다 : <service name = "Events"> <endpoint address = "json"binding = "webHttpBinding"behaviorConfiguration = "jsonBehavior"contract = "IEvents"/>. 내 IEvents에 인터페이스에 [ServiceContract] 속성이 있으므로 이유를 모르겠습니다. </ service>
PositiveGuy

내가 얻을 수 44652이 /에서는 MyResource / JSON : 로컬 호스트 일을을하지만 난 작업에 ID 얻을 수없는 로컬 호스트 : 44652 /에서는 MyResource / 98 / JSON을 . "/ {id}"의 UriTemplate을 추가하려고 시도했지만 "events / {id}도 시도했지만 서비스를 실행하려고 할 때 찾지 못했습니다. 첫 번째 작업 만 수행 할 수 있습니다. 작업에.
PositiveGuy

2
실제 파일이 없으면 어떻게 작동합니까? 난 그냥, 404 오류를 얻을 수가 뭔가 빠진해야
RoboJ1M

39

이 글은 이미 "커뮤니티 위키 (wiki)"에 의해 아주 좋은 답변을 받았으며 Rick Strahl의 웹 블로그를 볼 것을 권장합니다. WCF Rest에 관한 많은 좋은 글 이 있습니다. . 있습니다.

나는 이런 종류의 MyService-service를 얻기 위해 둘 다를 사용했다. 그러면 jQuery의 REST 인터페이스 또는 Java의 SOAP를 사용할 수있다.

이것은 내 Web.Config에서 온 것입니다.

<system.serviceModel>
 <services>
  <service name="MyService" behaviorConfiguration="MyServiceBehavior">
   <endpoint name="rest" address="" binding="webHttpBinding" contract="MyService" behaviorConfiguration="restBehavior"/>
   <endpoint name="mex" address="mex" binding="mexHttpBinding" contract="MyService"/>
   <endpoint name="soap" address="soap" binding="basicHttpBinding" contract="MyService"/>
  </service>
 </services>
 <behaviors>
  <serviceBehaviors>
   <behavior name="MyServiceBehavior">
    <serviceMetadata httpGetEnabled="true"/>
    <serviceDebug includeExceptionDetailInFaults="true" />
   </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
   <behavior name="restBehavior">
    <webHttp/>
   </behavior>
  </endpointBehaviors>
 </behaviors>
</system.serviceModel>

그리고 이것은 내 서비스 클래스입니다 (.svc-codebehind, 인터페이스 필요 없음).

    /// <summary> MyService documentation here ;) </summary>
[ServiceContract(Name = "MyService", Namespace = "http://myservice/", SessionMode = SessionMode.NotAllowed)]
//[ServiceKnownType(typeof (IList<MyDataContractTypes>))]
[ServiceBehavior(Name = "MyService", Namespace = "http://myservice/")]
public class MyService
{
    [OperationContract(Name = "MyResource1")]
    [WebGet(ResponseFormat = WebMessageFormat.Xml, UriTemplate = "MyXmlResource/{key}")]
    public string MyResource1(string key)
    {
        return "Test: " + key;
    }

    [OperationContract(Name = "MyResource2")]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource/{key}")]
    public string MyResource2(string key)
    {
        return "Test: " + key;
    }
}

실제로 Json 또는 Xml 만 사용하지만 둘 다 데모 목적으로 사용됩니다. 그것들은 데이터를 얻기 위해 GET 요청입니다. 데이터를 삽입하려면 속성이있는 메소드를 사용하십시오.

[OperationContract(Name = "MyResourceSave")]
[WebInvoke(Method = "POST", ResponseFormat = WebMessageFormat.Json, UriTemplate = "MyJsonResource")]
public string MyResourceSave(string thing){
    //...

이러한 WebGet 및 WebInvoke 속성을 추가하면 어떤 이점을 얻을 수 있는지 알고 싶습니다.
Darrel Miller

2
localhost / MyService.svc / MyXmlResource / test 브라우저로 요청할 수 있으며 Json 또는 Xml 형식을 명시 적으로 말하십시오. 동일한 방법으로 두 가지 모두에 응답하려면 다음 링크를 참조하십시오 : blogs.msdn.com/dotnetinterop/archive/2008/11/04/…
Tuomas Hietanen

이것은 테스트 목적입니다. 엔드 포인트가 작동하는지 확인하십시오. SoapUI를 보셨습니까? soapui.org
대럴 밀러

@ TuomasHietanen-webHttp 동작을 사용하여 JSON 유형 응답을 얻지 못하지만 enableWebScript를 사용하면 JSON 유형 응답을 얻습니다. ResponseFormat을 WebMessageFormat.Json으로 넣었습니다. 반면에 enableWebScript 동작을 사용하면 URItemplate을 사용할 수 없습니다. 어떤 아이디어?
smile.al.d.way

1
@CoffeeAddict-왜 인터페이스를 사용해야합니까? 인터페이스가 필요하십니까? 이 인터페이스는 재사용하지 않습니다. 이것은 더 간단합니다.
Tuomas Hietanen 10

25

단일 웹 서비스 만 개발하고 여러 엔드 포인트 (예 : SOAP, REST, XML, JSON, CSV, HTML 출력)에서 호스팅하려는 경우. 또한 개발할 모든 서비스를 구성없이 SOAP 및 REST 엔드 포인트에서 자동으로 사용할 수있는 바로이 목적을 위해 구축 한 ServiceStack 사용을 고려해야 합니다.

안녕하세요 단지 (어떤 설정이 필요 없음)와 서비스를 간단한을 만드는 방법 예를 보여줍니다 :

public class Hello {
    public string Name { get; set; }
}

public class HelloResponse {
    public string Result { get; set; }
}

public class HelloService : IService
{
    public object Any(Hello request)
    {
        return new HelloResponse { Result = "Hello, " + request.Name };
    }
}

다른 구성이 필요하지 않으며이 서비스는 다음 위치에서 REST를 통해 즉시 사용할 수 있습니다.

또한 친숙한 HTML 출력 ( 내장 된 HTTP 클라이언트와 함께 호출 할 때)이 내장되어 있습니다. Incept : text / html 브라우저 있어 서비스 출력을보다 잘 시각화 할 수 있습니다.

다른 REST 동사를 처리하는 것도 간단합니다. 다음은 C #의 1 페이지에있는 완전한 REST 서비스 CRUD 앱입니다 (WCF 구성에 소요되는 것보다 적음).


7

MSDN에는 지금이 기사가있는 것 같습니다.

https://msdn.microsoft.com/en-us/library/bb412196(v=vs.110).aspx

소개 :

기본적으로 WCF (Windows Communication Foundation)는 끝점을 SOAP 클라이언트에서만 사용할 수 있도록합니다. 방법 : 기본 WCF 웹 HTTP 서비스 만들기에서 비 SOAP 클라이언트가 엔드 포인트를 사용할 수 있습니다. 동일한 계약을 웹 엔드 포인트 및 SOAP 엔드 포인트로 양방향으로 사용 가능하게하려는 경우가 있습니다. 이 주제는이를 수행하는 방법의 예를 보여줍니다.


3

REST 엔드 포인트에 동작 구성을 정의해야 합니다.

<endpointBehaviors>
  <behavior name="restfulBehavior">
   <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
  </behavior>
</endpointBehaviors>

또한 서비스

<serviceBehaviors>
   <behavior>
     <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
      <serviceDebug includeExceptionDetailInFaults="false" />
   </behavior>
</serviceBehaviors>

동작 후 다음 단계는 바인딩입니다. 예를 들어 SOAP 끝점에 대한 basicHttpBinding 및 REST에 대한 webHttpBinding 입니다.

<bindings>
   <basicHttpBinding>
     <binding name="soapService" />
   </basicHttpBinding>
   <webHttpBinding>
     <binding name="jsonp" crossDomainScriptAccessEnabled="true" />
   </webHttpBinding>
</bindings>

마지막으로 서비스 정의에서 2 개의 엔드 포인트를 정의해야합니다. REST 서비스가 필요하지 않은 엔드 포인트의 address = ""에주의하십시오.

<services>
  <service name="ComposerWcf.ComposerService">
    <endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="ComposerWcf.Interface.IComposerService" />
    <endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="ComposerWcf.Interface.IComposerService" />
    <endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
  </service>
</services>

서비스 인터페이스에서 속성을 사용하여 작업을 정의합니다.

namespace ComposerWcf.Interface
{
    [ServiceContract]
    public interface IComposerService
    {
        [OperationContract]
        [WebInvoke(Method = "GET", UriTemplate = "/autenticationInfo/{app_id}/{access_token}", ResponseFormat = WebMessageFormat.Json,
            RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped)]
        Task<UserCacheComplexType_RootObject> autenticationInfo(string app_id, string access_token);
    }
}

모든 당사자와 함께 WCF system.serviceModel 정의가됩니다.

<system.serviceModel>

  <behaviors>
    <endpointBehaviors>
      <behavior name="restfulBehavior">
        <webHttp defaultOutgoingResponseFormat="Json" defaultBodyStyle="Wrapped" automaticFormatSelectionEnabled="False" />
      </behavior>
    </endpointBehaviors>
    <serviceBehaviors>
      <behavior>
        <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="false" />
      </behavior>
    </serviceBehaviors>
  </behaviors>

  <bindings>
    <basicHttpBinding>
      <binding name="soapService" />
    </basicHttpBinding>
    <webHttpBinding>
      <binding name="jsonp" crossDomainScriptAccessEnabled="true" />
    </webHttpBinding>
  </bindings>

  <protocolMapping>
    <add binding="basicHttpsBinding" scheme="https" />
  </protocolMapping>

  <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />

  <services>
    <service name="ComposerWcf.ComposerService">
      <endpoint address="" behaviorConfiguration="restfulBehavior" binding="webHttpBinding" bindingConfiguration="jsonp" name="jsonService" contract="ComposerWcf.Interface.IComposerService" />
      <endpoint address="soap" binding="basicHttpBinding" name="soapService" contract="ComposerWcf.Interface.IComposerService" />
      <endpoint address="mex" binding="mexHttpBinding" name="metadata" contract="IMetadataExchange" />
    </service>
  </services>

</system.serviceModel>

두 엔드 포인트를 테스트하기 위해 WCFClient to SOAPPostMan to REST 를 사용할 수 있습니다 .


예상대로 작동 잘

0

이것이 내가 작동하게 만든 것입니다. 엔드 포인트 동작 내에
webHttp automaticFormatSelectionEnabled = "true" 를 입력하십시오 .

[ServiceContract]
public interface ITestService
{

    [WebGet(BodyStyle = WebMessageBodyStyle.Bare, UriTemplate = "/product", ResponseFormat = WebMessageFormat.Json)]
    string GetData();
}

public class TestService : ITestService
{
    public string GetJsonData()
    {
        return "I am good...";
    }
}

내부 서비스 모델

   <service name="TechCity.Business.TestService">

    <endpoint address="soap" binding="basicHttpBinding" name="SoapTest"
      bindingName="BasicSoap" contract="TechCity.Interfaces.ITestService" />
    <endpoint address="mex"
              contract="IMetadataExchange" binding="mexHttpBinding"/>
    <endpoint behaviorConfiguration="jsonBehavior" binding="webHttpBinding"
              name="Http" contract="TechCity.Interfaces.ITestService" />
    <host>
      <baseAddresses>
        <add baseAddress="http://localhost:8739/test" />
      </baseAddresses>
    </host>
  </service>

엔드 포인트 동작

  <endpointBehaviors>
    <behavior name="jsonBehavior">
      <webHttp automaticFormatSelectionEnabled="true"  />
      <!-- use JSON serialization -->
    </behavior>
  </endpointBehaviors>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.