2013-01-14 3 views
6

제목에 다소 차이가 있습니다. 경로마다 다르게 동작하도록 JSON MediaTypeFormatter를 구성하려고합니다.웹 API의 Route Formatter 구성에 따라

특히 WebAPI에는 동일한 컨트롤러에 매핑되는 두 개의 경로가 있습니다. 각 경로는 동일한 작업을 수행하고 동일한 데이터를 반환하지만 기존 소비자와의 역 비교를 위해 출력의 형식을 약간 다르게 지정해야합니다.

Controller에 코드를 입력하여 요청이 기존 경로 또는 새 경로에 들어 왔는지 확인하고 그에 따라 포매터를 변경할 수 있습니다.

필요한 경우 포맷터를 변경하기 위해 ActionFilter를 사용할 수도 있습니다.

그러나 경로 수준마다 형식 작성기를 구성하는 방법이 있는지 궁금해했습니다. 그 이유는 이것이 API가 다르게 동작하는 추상화 수준이기 때문입니다. 이것은 Route Configuration 또는 Delegate Handler 시점 일 수 있습니다.

제안 사항?

답변

6

나는 당신이 JSONs이 얼마나 많은 다른 완전히 잘 모르겠어요 정확히 당신이 그들과 함께 일을하지만, 당신이 저를 요구하는 경우에, 나는 포맷터에서 그것을 할 것 :

public class MyJsonMediaTypeFormatter : JsonMediaTypeFormatter 
{ 
    private IHttpRouteData _route; 

    public override MediaTypeFormatter GetPerRequestFormatterInstance(Type type, HttpRequestMessage request, System.Net.Http.Headers.MediaTypeHeaderValue mediaType) 
    { 
     _route = request.GetRouteData(); 
     return base.GetPerRequestFormatterInstance(type, request, mediaType); 
    } 

    public override System.Threading.Tasks.Task WriteToStreamAsync(Type type, object value, System.IO.Stream writeStream, HttpContent content, TransportContext transportContext) 
    { 
     if (_route.Route.RouteTemplate.Contains("legacy")) 
     { 
      //here set the SerializerSettings for non standard JSON 
      //I just added NullValueHandling as an example 
      this.SerializerSettings = new JsonSerializerSettings 
       { 
        NullValueHandling = NullValueHandling.Ignore 
       }; 
     } 

     return base.WriteToStreamAsync(type, value, writeStream, content, transportContext); 
    } 
} 

당신은 것 디폴트의 ​​JsonMEdiaTypeFormatter를 이것에 옮겨 놓습니다.

웹 API에서
config.Formatters.RemoveAt(0); 
    config.Formatters.Insert(0, new MyJsonMediaTypeFormatter()); 

만 특정 경로에서 실행 DelegatingHandler을 가질 수 있지만, Formatters 컬렉션 글로벌이기 때문에 그건 정말 이해가되지 않습니다 그래서 런타임도 route-에서 해당 수정도 아무런 문제가 없다 범위 핸들러.

+0

예, 맞춤 MediaTypeFormatter 사용을 고려했습니다. 당신의 위의 예는 v를 달성하려고하는 것과 비슷합니다. 그러나 로직을 적용하면 애플리케이션 로직을 상당히 독립적 인 무언가에 도입 할 수 있다고 우려하고 있습니다. 나는 까다 롭다. 당신의 해결책은 확실히 효과가있을 것이다. 그러나 내 마음 속에있는 순수 주의자는 내 관심사를 잘하고 진정으로 분리하는 것을 좋아한다. –

+1

* IControllerConfiguration * http://blogs.msdn.com/b/jmstall/archive/2012/05/11/per-controller-configuration-in-webapi.aspx를 통해 컨트롤러 별 구성을 사용할 수 있으며이를 등록하십시오 적용되는 하나의 컨트롤러에 대해서만 "사용자 지정"포맷터. 이 방식으로 핵심 응용 프로그램은 여전히 ​​기본 포맷터를 사용하지만 더 많은 요구 사항이있는 하나의 컨트롤러는 특정 포맷터를 사용합니다. –

+0

액션 필터를 사용하는 것과 실제로 다른 점을 실제로 볼 수 없습니다. 실제로 IControllerConfiguration 속성을 사용하여 경로/요청 문맥 정보에 대한 액세스 권한이 없기 때문에이 작업을 수행 할 수 있는지 확신 할 수 없습니다. –