2014-03-24 3 views
5

WCF/REST 서비스 프로젝트를 MVC/WebAPI로 변환하려고합니다. 서비스 계층은 여러 최종 시스템에 대한 래퍼로 여러 번 구현되며 모든 구현은 인터페이스 (IContract)에 정의 된 공통 계약을 준수합니다. WCF를 사용하여 웹 서비스 메서드로 노출 된 각 메서드에 대해 [WebInvoke][OperationContract] 특성을 정의했습니다. WebAPI에서 이것은 컨트롤러에 정의 된 속성 라우팅으로 단순화 될 수 있습니다. 그러나 인터페이스에 정의 된 경로 속성을 유지하여 모든 구현이 유사하게 동작하도록하고 싶습니다.인터페이스에 정의 된 WebApi 특성 라우팅

public interface IContract 
{ 
    [Route("Version")] 
    [HttpGet] 
    string GetVersion(); 
} 

가 나는 또한 추상 기본 클래스를 만드는 것이 좋습니다,하지만이 다른 StackOverflow question 차종 :

여기
[ServiceContract] 
public interface IContract 
{ 
    [WebInvoke(UriTemplate = "Version", Method = "GET", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)] 
    [OperationContract] 
    string GetVersion(); 
} 

내가 작업을 얻을 수 있었으면 된 내용은 다음과 같습니다 여기

은 이전 인터페이스의 샘플입니다 WebAPI 속성 라우팅을 사용하는 [WebInvoke(UriTemplate)]을 적절하게 대체 할 수 없다고 생각합니다. 그렇다면 누군가가 비슷한 지원 기술을 가르쳐 줄 수 있습니까?

감사

답변

1

당신은 Route 속성을 가진 인터페이스를 장식 할 수 없다. 이것은 웹 프레임 워크가 자체 프레임 워크 내에서 작동하기 때 문입니다. 경로를 결정하기 위해 유형이 ApiController 인 모든 오브젝트를 검사합니다. 기본적으로 사용자 지정 컨트롤러의 메서드 특성을 조사하여 라우팅을 만듭니다. 맞춤 IContract 인터페이스를 찾지 않으므로 이러한 라우팅을 신경 쓰지 않습니다.

웹 API의 코드베이스를 변경하여 인터페이스에서 Route 속성을 읽고 처리하는 경우 어떻게 작동합니까? 인터페이스는 계약이며 기능을 포함하지 않습니다. 그래서 "Version"에 대한 경로를 찾으면 어떤 컨트롤러 구현/인스턴스로 매핑할까요? 임의로 찾은 첫 번째 것은 IContract에 할당 할 수 있습니까? 마지막 하나? 모두들? 그리고 그것들 모두가 있다면 N 컨트롤러 메소드를 한 번에 어떻게 실행합니까?

저는 속성 라우팅에 대한 이해를 평가해야한다고 생각합니다. 웹 API 프레임 워크는이 라우트에 대해이 제어기에서이 메소드를 사용하도록 지시합니다. 실행할 파생 클래스를 결정할 수 없으므로이 인터페이스를 추상화 할 수 없습니다.

+1

는, 나는 WCF REST는 인터페이스에 배치'[WebInvoke의 (UriTemplate)] '속성의 사용을 통해 매우 비슷한 접근 방식을 지원하는 것은 놀라운 것 같아요. 더 나은 구조는 아마도 라우트 속성을 가진 추상 기본 클래스를 구현하는 것이고, 웹 API 버전 5.2가이 시나리오를 지원해야하는 것처럼 보입니다 ([이 업데이트 된 답변] (http://stackoverflow.com/a/19989344/) 참조). 44770)) – tbetts42

+0

WCF REST에서 당신의 이야기를 들었지만, 개인적으로 그것이 튼튼한 원칙을 깨뜨린다고 생각합니다. 클래스를 구현하는 것에 대해 인터페이스를 알면 적어도 내 눈에는 목적을 상실 할 수 있습니다. – Haney

4

ASP.NET 팀에서 무엇이 나오는지 더 자세히 조사한 후 System.Web.Http.Routing.IDirectRouteProvider 확장 성이 우리의 요구를 충족시킬 것으로 예상됩니다. 이 글을 쓰는 시점에서 ASP.NET 야간 빌드를 사용할 때만 사용할 수 있지만, 준비가 끝날 때까지는 RTM 또는 적어도 CTP에 도달 할 것으로 기대됩니다. MapHttpAttributeRoutes() 방법에 새 IDirectRouteProvider을 통과

Application_Start 또는 WebApiConfig.Register()에서 :

다음 코드는 (https://aspnetwebstack.codeplex.com/workitem/1464 원본 소스) 위에 내 예를 들어이를 구현하는 방법을 보여줍니다.

config.MapHttpAttributeRoutes(new CustomDirectRouteProvider()); 

다음과 같이 경로 공급자를 정의하십시오. 이것은 기본적으로 속성 상속을 켜기 때문에 기본 클래스 (인터페이스는 아님)에서 라우트를 읽습니다.내 경우

public class CustomDirectRouteProvider : DefaultDirectRouteProvider 
{ 
    protected override IReadOnlyCollection<IDirectRouteFactory> GetActionRouteFactories(HttpActionDescriptor actionDescriptor) 
    { 
     return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(inherit: true); 
    } 
} 

, 우리는 WebAPI 방법에 [Route] 특성을 제공하는 추상적 인 BaseApiController를 만들었습니다.

public abstract class BaseApiController : ApiController, IContract 
{ 
    [Route("Version")] 
    [HttpGet] 
    public abstract string GetVersion(); 

} 

우리의 종단 시스템은 이전에 IContract 인터페이스를 구현 한 WCF REST 서비스 종단점이었습니다. WebAPI의 경우 컨트롤러는 이제 BaseApiController에서 파생됩니다. (우리는 ContractService에서 ContractServiceController로 이름을 변경해야했습니다.) 이전 버전과의 호환성을 위해 IContract를 유지했지만 BaseApiController에서 구현되었습니다. [RoutePrefix] 속성은이 경우 컨트롤러의 루트 URL에 정의되어 있습니다. 그게 내가 동의 완전히 합리적인 설명이이지만

[RoutePrefix("")] 
public class TestController : BaseApiController 
{ 
    public override string GetVersion(); 
    { 
     return "Version 1.0.0.0"; 
    } 
} 
관련 문제