25

給定以下webapiconfig;根據請求從MVC web api返回xml或json

config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

和這個控制器;

public class ProductsController : ApiController 
    { 
     Product[] _products = new Product[] 
     { 
      new Product { Id = 1, Name = "Tomato Soup", Category = "Groceries", Price = 1 }, 
      new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M }, 
      new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M } 
     }; 

     public IEnumerable<Product> GetAllProducts() 
     { 
      return _products; 
     } 
    } 

使用URL http://localhost/api/Products我得到一個XML格式的產品列表。

我想要做的是有選擇根據請求返回json或xml。所以對於json來說,這將是;

http://localhost/api/Products.json 

對於XML,它會是;

http://localhost/api/Products.xml 

同樣;

http://localhost/api/Products.json/1/ 
http://localhost/api/Products.xml/1/ 

這是可能的,我將如何實現此功能?

另一種可能是類似的;

http://localhost/api/json/Products/ 

回答

37

是的,你可以實現與AddUriPathExtensionMapping

你可以這樣創建路線:

routes.MapHttpRoute(
    name: "Api UriPathExtension", 
    routeTemplate: "api/{controller}.{extension}/{id}", 
    defaults: new { id = RouteParameter.Optional, extension = RouteParameter.Optional } 
); 

routes.MapHttpRoute(
    name: "Api UriPathExtension ID", 
    routeTemplate: "api/{controller}/{id}.{extension}", 
    defaults: new { id = RouteParameter.Optional, extension = RouteParameter.Optional } 
); 

然後,你需要擴展格式化:

config.Formatters.JsonFormatter.AddUriPathExtensionMapping("json", "application/json"); 
    config.Formatters.XmlFormatter.AddUriPathExtensionMapping("xml", "text/xml"); 

務必加入對System.Net.Http.Formatting的引用,因爲這些方法是擴展方法和intel lisense默認情況下不會看到它們。

還記得在這個例子中,你仍然必須發出具有適當內容類型的請求。但是,如果您希望通過瀏覽器地址欄直接使用這些地址欄,則可以映射到「text/html」。

我寫了一篇博客文章所有前一陣子 - 這應該是有益的,帶你進入更多的細節http://www.strathweb.com/2012/04/different-mediatypeformatters-for-same-mediaheadervalue-in-asp-net-web-api/

+0

的路線似乎工作,但延長的東西沒有做任何事情。我將這些添加到global.asax,這是一個問題嗎? – ChrisBint

+5

Chris,使用{ext}代替{extension},因爲{ext}似乎是硬編碼來引用映射的格式化程序。 – MCattle

+0

偉大的線程。像@ MCattle說的,永遠記住:EXT而不是EXTENSION –