首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> ASP.NET 基礎

ASP.NET Web API 強制回傳 JSON 的三種方法完整比較

     編輯:ASP.NET 基礎

預設行為

Web API 依據 Accept 標頭進行內容協商:瀏覽器通常送 text/html, application/xhtml+xml, application/xml;q=0.9,導致預設回傳 XML。若需強制 JSON,有三種主流做法。

方法一:移除 XML Formatter(全域、最簡單)

// Global.asax.cs
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);

    // 移除 XML 格式化器,只保留 JSON
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}

優點:一行程式碼、全域生效。
缺點:string 回傳型別會被序列化為 "value"(含雙引號),非純 JSON 字串;無法針對個別 Action 控制。

方法二:自訂回傳 HttpResponseMessage(完全控制、萬金油)

public HttpResponseMessage GetUser(int id)
{
    var user = _service.GetUser(id);
    var json = JsonConvert.SerializeObject(user); // Newtonsoft.Json
    return new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new StringContent(json, Encoding.UTF8, "application/json")
    };
}

// 字串回傳不被加引號
public HttpResponseMessage GetRawString()
{
    string raw = "hello";
    return new HttpResponseMessage(HttpStatusCode.OK)
    {
        Content = new StringContent(raw, Encoding.UTF8, "application/json") // 純字串內容
    };
}

為避免重複撰寫,可封裝擴充方法:

public static class HttpResponseMessageExtensions
{
    public static HttpResponseMessage AsJson(this object obj, HttpStatusCode status = HttpStatusCode.OK)
    {
        string content;
        if (obj is string || obj is char)
            content = obj.ToString(); // 字串直接輸出,不序列化
        else
            content = JsonConvert.SerializeObject(obj);

        return new HttpResponseMessage(status)
        {
            Content = new StringContent(content, Encoding.UTF8, "application/json")
        };
    }
}

// 使用
public HttpResponseMessage GetUser(int id) => _service.GetUser(id).AsJson();
public HttpResponseMessage GetMessage() => "操作成功".AsJson();

方法三:自訂 IContentNegotiator(針對特定路由/控制器)

public class JsonOnlyNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter _formatter = new JsonMediaTypeFormatter();

    public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable formatters)
    {
        return new ContentNegotiationResult(_formatter, new MediaTypeHeaderValue("application/json"));
    }
}

// WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });

    // 全域套用
    config.Services.Replace(typeof(IContentNegotiator), new JsonOnlyNegotiator());

    // 或針對特定控制器
    // config.MapHttpAttributeRoutes();
    // [JsonOnly] 自訂 Attribute 套用在 Controller/Action
}

優點:可精細控制套用範圍、保留內容協商架構。
缺點:程式碼較多、同樣面臨 string 加引號問題。

比較總覽

方法適用範圍string 回傳複雜度備註
移除 XML Formatter全域變成 "str"極低最快,但副作用大
HttpResponseMessage 手動序列化單一 Action / 擴充方法純字串中最靈活,推薦封裝為 BaseController 或擴充方法
IContentNegotiator全域 / 控制器 / Action變成 "str"高架構純正,但需自行處理 string 特例

現代化建議:ASP.NET Core 原生支援

ASP.NET Core MVC / Web API 預設即回傳 JSON,且 string 回傳為純文字(text/plain),若需 JSON 字串請回傳 JsonResult 或物件。無需任何設定即可獲得正確行為。

總結

  • 舊專案快速修正:方法一(移除 XML Formatter),注意 string 加引號問題。
  • 追求彈性與正確性:方法二(手動 HttpResponseMessage + 擴充方法),掌控序列化細節。
  • 架構潔癖/需局部控制:方法三(自訂 Negotiator)。
  • 新專案:直接用 ASP.NET Core,零設定強制 JSON。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved