2013-01-14 34 views
6

标题或多或少地说明了一切。 我想配置JSON MediaTypeFormatter行为不同每路线。Web API中的每个路由格式化程序配置

具体来说,我有两个路线在我的WebAPI映射到相同的控制器。 每条路线执行相同的操作并返回相同的数据,但出于与现有消费者的向后可比性的原因,他们必须以不同的方式格式化其输出。

我可以在控制器中放置一些代码,以确定请求是进入传统路由还是新路由,并相应地更改格式化程序。

我也可以使用ActionFilter来根据需要更改格式器。

但是我想知道是否有一种方法可以在每个路由级别配置格式化程序,因为这是我的API行为不同的抽象级别。这可能在路由配置或委托处理程序中。

有什么建议吗?

回答

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。

config.Formatters.RemoveAt(0); 
    config.Formatters.Insert(0, new MyJsonMediaTypeFormatter()); 

在网页API,你可以有DelegatingHandler只有特定的路线上运行,但并没有真正意义,因为Formatters收集全球因此在修改,在运行时即使从没有为route-点范围处理程序。

+0

是的,我曾考虑使用自定义的MediaTypeFormatter;上面的例子与我试图达到的目标类似;但是我担心把逻辑引入到应该独立于应用程序的应用程序逻辑中。我很挑剔,我知道,你的解决方案肯定会奏效 - 但我的纯粹主义者喜欢把我的担忧保持得很好,并且真正分开。 –

+1

您可以使用每控制器配置(通过* IControllerConfiguration * http://blogs.msdn.com/b/jmstall/archive/2012/05/11/per-controller-configuration-in-webapi.aspx)并注册此“自定义”格式化程序仅适用于其应用的一个控制器。这样核心应用程序仍然使用默认格式化程序,但具有更多要求的一个控制程序使用特定格式化程序。 –

+0

我实际上并没有看到与使用Action Filter完全不同。事实上,我不确定我是否可以通过IControllerConfiguration属性来实现此目的,因为他们无权访问路由/请求上下文信息。 –