讓 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 中處理,例如:

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

留言

這個網誌中的熱門文章

[C#]Windows 10 停用與啟用網路卡(連線)[手把手教程][原創]

ASP.NET Web API 將傳回的值轉換從控制器動作至 HTTP 回應訊息的方式。

[C#]程式更改電腦IP位置與電腦名稱