2009-03-18 1 views

답변

5

@Marc Gravell 's의 반대편에서 작동하는 다른 해결책이 있습니다. 계약서를 복제하는 대신 서비스 구현에서 두 가지 클래스를 파생시킵니다. 이것들은 형식 ​​별명 일뿐입니다. WCF 정품 인증 시스템 (적어도 IIS)은 다른 URL에서 동일한 서비스 유형을 활성화 할 수 없기 때문에 필요합니다. (왜 Gravell의 솔루션이이 문제에 부딪 치지 않았는지 알 수 없습니다. 동일한 사이트의 다른 URL에서 동일한 서비스 클래스를 활성화하려고하면 "URI에 대한 등록이 이미 존재합니다 ..."라는 메시지가 나타납니다. pox 및 json과 동일한 서비스를 실행하려는 경우이 문제는 단지 입니다. 응답 형식을 원하는대로 제어하려면이 해결 방법이 필요하지 않습니다.

내 솔루션의 핵심 개념은 동일한 서비스에 2 개의 다른 URI를 사용하고 엔드 포인트 동작을 사용하여 기본 아웃 바운드 응답 형식을 설정하는 것입니다. this question에서 자세한 내용을 확인할 수 있습니다. 개념적 순결이라는 질문에 대해서도 언급합니다. 계약 속성을 사용하여 네트워크 프로토콜의 일부인 속성을 지정해야합니까? 나는 Marc Gravell이이 문제를 다루는 것이 그 자체로 유효하다고 생각하지만 WCF의 원래 개념은 일관성이 없습니다. 계약은 프로토콜 스택에서 추상화 된 것으로 간주됩니다. 그러나 엔드 포인트 동작은 모든 REST 관련 속성을 지정할 수 없으므로 URI 템플리트 및 인바운드 형식의 속성을 사용해야합니다.

REST가 다르게 구현 되었습니까? WCF의 설계자가 일반적인 프레임 워크를 설계하는 데 탁월한 성과를 보였지만 REST가 발생하지는 않는다고 생각합니다. URI 템플릿과 같은 것은 실제로 계약에 속하는 것 같습니다.

충분한 토크! 여기에 코드가 있습니다. 먼저 web.config 파일. 이것은 마술이 일어나는 곳입니다. 이 예제에서는 WCF 4 구성 기반 활성화를 사용하고 있지만 두 개의 URI를 나타내는 두 개의 svc 파일을 사용하여 동일한 작업을 수행 할 수도 있습니다.

<?xml version="1.0"?> 
<configuration> 
    <system.web> 
    <compilation debug="true" targetFramework="4.0" /> 
    </system.web> 
    <system.serviceModel> 
    <services> 
     <service name="StackOverflow.QuoteOfTheDayAsJson"> 
     <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
        behaviorConfiguration="jsonBehavior" /> 
     </service> 
     <service name="StackOverflow.QuoteOfTheDayAsPox"> 
     <endpoint binding="webHttpBinding" contract="StackOverflow.IQuoteOfTheDay" 
        behaviorConfiguration="poxBehavior" /> 
     </service> 
    </services> 
    <behaviors> 
     <endpointBehaviors> 
     <behavior name="jsonBehavior"> 
      <webHttp defaultOutgoingResponseFormat="Json" /> 
     </behavior> 
     <behavior name="poxBehavior"> 
      <webHttp defaultOutgoingResponseFormat="Xml"/> 
     </behavior> 
     </endpointBehaviors> 
    </behaviors> 
    <serviceHostingEnvironment multipleSiteBindingsEnabled="false"> 
     <serviceActivations> 
     <add relativeAddress="QuoteOfTheDayJson.svc" 
      service="StackOverflow.QuoteOfTheDayAsJson"/> 
     <add relativeAddress="QuoteOfTheDayPox.svc" 
      service="StackOverflow.QuoteOfTheDayAsPox"/> 
     </serviceActivations> 
    </serviceHostingEnvironment> 
    </system.serviceModel> 
</configuration> 

그리고 여기에는 서비스 계약, 서비스 구현을 포함, 코드, 그리고 필요한 유형 별칭이 작동하도록 :이 유형 별칭의 필요성이 없었다면

namespace StackOverflow 
{ 
    [DataContract] 
    public class Quotation 
    { 
     [DataMember] 
     public string Text { get; set; } 

     [DataMember] 
     public string Author { get; set; } 
    } 

    [ServiceContract] 
    public interface IQuoteOfTheDay 
    { 
     [OperationContract] 
     [WebInvoke(Method="GET", UriTemplate="GetTodaysQuote")] 
     Quotation GetTodaysQuote(); 
    } 

    public class QuoteOfTheDayImp : IQuoteOfTheDay 
    { 
     public Quotation GetTodaysQuote() 
     { 
      return new Quotation() 
      { 
       Text = "Sometimes it's better to appologize for not asking permission", 
       Author = "Admiral Grace Murray Hopper" 
      }; 
     } 
    } 

    /// <summary> 
    /// A type alias used for json activation 
    /// </summary> 
    public class QuoteOfTheDayAsJson : QuoteOfTheDayImp 
    {} 

    /// <summary> 
    /// A type alias used for pox activation 
    /// </summary> 
    public class QuoteOfTheDayAsPox : QuoteOfTheDayImp 
    {} 
} 

을 , 나는 이것이 완전한 해결책이라고 말하고 싶다. 동시에 여러 형식을 지원하지 않으려는 경우 완벽한 솔루션입니다. 이는 하나의 계약 만 있기 때문에 두 계약을 동기화 할 필요가 없다는 점에서 다중 계약 솔루션보다 우수합니다.

+0

환상적인 답변! –

관련 문제