讓 Web API 預設傳回 JSON 字串
ASP.NET MVC 4 Beta 版是採用 .NET 自家的 DataContractJsonSerializer 來處理 JSON 的序列化工作,不是那麼好用,而正式版已經改用 Json.NET 作為預設的序列化工具,也就不再需要額外寫 media type formatter 來取代預設的序列化工具了。
可是 Web API 會因為瀏覽器送出的 Accept 標頭而傳回不同的格式,例如 IE 會取得 JSON,並詢問要開啟檔案還是另存檔案;Chrome 則會取得 XML 格式的回應。其中原委可參考保哥的文章:如何讓 ASP.NET Web API 無論任何要求都回應 JSON 格式。文中也有提到解法,是在 Global.asax 裡面的 Application_Start 事件中動手腳。另一種類似的解法是在 App_Start\WebApiConfig.cs 中處理,例如:
關鍵在後面兩行 code。
這解法是在 stackoverflow.com 上爬來的,其優點是依然保有傳回 XML 格式的能力,亦即預設傳回 JSON,但如果前端發出的 HTTP request 的 Accept 標頭是 "text/xml",就會傳回 XML。
範例程式
前面的手腳做完以後,底下的範例程式就能順利傳回 JSON 字串了。
你可以看到,TestJsonController 傳回的型別是 Dictionary<string, string>,但前端收到的會是已經自動幫你序列化的 JSON 字串,如下圖:
所以在寫 ASP.NET Web API 時,就不用自己寫 code 去處理 JSON 序列化的動作。如果像下面這樣畫蛇添足:
前端瀏覽器看到的 JSON 就會有一堆多餘的反斜線:
可是 Web API 會因為瀏覽器送出的 Accept 標頭而傳回不同的格式,例如 IE 會取得 JSON,並詢問要開啟檔案還是另存檔案;Chrome 則會取得 XML 格式的回應。其中原委可參考保哥的文章:如何讓 ASP.NET Web API 無論任何要求都回應 JSON 格式。文中也有提到解法,是在 Global.asax 裡面的 Application_Start 事件中動手腳。另一種類似的解法是在 App_Start\WebApiConfig.cs 中處理,例如:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}
}
關鍵在後面兩行 code。
這解法是在 stackoverflow.com 上爬來的,其優點是依然保有傳回 XML 格式的能力,亦即預設傳回 JSON,但如果前端發出的 HTTP request 的 Accept 標頭是 "text/xml",就會傳回 XML。
範例程式
前面的手腳做完以後,底下的範例程式就能順利傳回 JSON 字串了。
using System.Collections.Generic;
using System.Web.Http;
namespace MvcAppDemo1.Controllers.Api
{
public class TestJsonController : ApiController
{
public Dictionary<string, string> Get()
{
var result = new Dictionary<string, string>()
{
{"001", "Banana"},
{"002", "Apple"},
{"003", "Orange"}
};
return result;
}
}
}
你可以看到,TestJsonController 傳回的型別是 Dictionary<string, string>,但前端收到的會是已經自動幫你序列化的 JSON 字串,如下圖:
所以在寫 ASP.NET Web API 時,就不用自己寫 code 去處理 JSON 序列化的動作。如果像下面這樣畫蛇添足:
using System.Collections.Generic;
using System.Web.Http;
using NewtonSoft.Json;
namespace MvcAppDemo1.Controllers.Api
{
public class TestJsonController : ApiController
{
public Dictionary<string, string> HandMadeJson()
{
var result = new Dictionary<string, string>()
{
{"001", "Banana"},
{"002", "Apple"},
{"003", "Orange"}
};
return JsonConvert.SerializeObject(result);
}
}
}
前端瀏覽器看到的 JSON 就會有一堆多餘的反斜線:
圖中網址列的紅色框不是框錯位置,而是跟後面的 Tip 5 要討論的議題有關。
資料來源: https://www.huanlintalk.com/2013/01/aspnet-web-api-and-json.html


留言
張貼留言