Bagaimana cara memaksa ASP.NET Web API untuk selalu mengembalikan JSON?


103

ASP.NET Web API melakukan negosiasi konten secara default - akan mengembalikan XML atau JSON atau jenis lain berdasarkan Acceptheader. Saya tidak membutuhkan / menginginkan ini, apakah ada cara (seperti atribut atau sesuatu) untuk memberi tahu Web API untuk selalu mengembalikan JSON?


Anda mungkin dapat melakukan ini dengan menghapus semua format kecuali json dariGlobalConfiguration.Configuration.Formatters
— Claudio Redi

Jawaban:


75

Hanya mendukung JSON di ASP.NET Web API - CARA YANG BENAR

Ganti IContentNegotiator dengan JsonContentNegotiator:

var jsonFormatter = new JsonMediaTypeFormatter();
//optional: set serializer settings here
config.Services.Replace(typeof(IContentNegotiator), new JsonContentNegotiator(jsonFormatter));

Implementasi JsonContentNegotiator:

public class JsonContentNegotiator : IContentNegotiator
{
    private readonly JsonMediaTypeFormatter _jsonFormatter;

    public JsonContentNegotiator(JsonMediaTypeFormatter formatter) 
    {
        _jsonFormatter = formatter;    
    }

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

4
di mana bagian pertama kode dipotong dan ditempel juga? Saya tidak melihat objek "config" di Global.asax saya. Dari manakah variabel itu berasal? artikel itu juga tidak menjelaskan.
— BuddyJoe

3
Periksa metode public static void Register (HttpConfiguration config) {...} di file WebApiConfig.cs yang telah digererasi oleh VS2012 pada pembuatan proyek
— Dmitry Pavlov

Apakah ini akan memaksa JSON dalam arti bahwa klien AcceptXML akan mendapatkan JSON, dan tidak akan mendapatkan 406 ?
— Luke Puplett

1
Saya dapat menjawab komentar / pertanyaan saya sendiri: XML mengembalikan apa pun Acceptheadernya.
— Luke Puplett

2
Ini merusak integrasi swashbuckle saya dan tampaknya itu terkait dengan masalah ini di github ( github.com/domaindrivendev/Swashbuckle/issues/219 ). Saya ingin menggunakan metode ini tetapi yang di bawah ini GlobalConfiguration...Clear()benar - benar berfungsi.
— seangwright

167

Hapus semua pemformat dan tambahkan kembali formatter Json.

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

EDIT

Saya menambahkannya ke Global.asaxdalam Application_Start().


dan di file mana .. ?? global.ascx .. ??
— shashwat

Dalam metode Application_Start () Anda
— Jafin

6
Filip W menjadi lebih baik sekarang :), lihat di sini strathweb.com/2013/06/…
— Tien Do

7
@TienDo - menautkan ke blog Filip sendiri?
— Phill

10

Philip W memiliki jawaban yang benar tetapi untuk kejelasan dan solusi yang berfungsi lengkap, edit file Global.asax.cs Anda agar terlihat seperti ini: (Perhatikan saya harus menambahkan referensi System.Net.Http.Formatting ke file yang dihasilkan stok)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;

namespace BoomInteractive.TrainerCentral.Server {
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class WebApiApplication : System.Web.HttpApplication {
        protected void Application_Start() {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            //Force JSON responses on all requests
            GlobalConfiguration.Configuration.Formatters.Clear();
            GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
        }
    }
}

9
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

Ini menghapus formatter XML dan dengan demikian default ke format JSON.


Sempurnakan semua yang dibutuhkan
— tfa

4

Terinspirasi oleh jawaban luar biasa Dmitry Pavlov, saya mengubahnya sedikit sehingga saya dapat memasang formatter apa pun yang ingin saya terapkan.

Penghargaan untuk Dmitry.

/// <summary>
/// A ContentNegotiator implementation that does not negotiate. Inspired by the film Taken.
/// </summary>
internal sealed class LiamNeesonContentNegotiator : IContentNegotiator
{
    private readonly MediaTypeFormatter _formatter;
    private readonly string _mimeTypeId;

    public LiamNeesonContentNegotiator(MediaTypeFormatter formatter, string mimeTypeId)
    {
        if (formatter == null)
            throw new ArgumentNullException("formatter");

        if (String.IsNullOrWhiteSpace(mimeTypeId))
            throw new ArgumentException("Mime type identifier string is null or whitespace.");

        _formatter = formatter;
        _mimeTypeId = mimeTypeId.Trim();
    }

    public ContentNegotiationResult Negotiate(Type type, HttpRequestMessage request, IEnumerable<MediaTypeFormatter> formatters)
    {
        return new ContentNegotiationResult(_formatter, new MediaTypeHeaderValue(_mimeTypeId));
    }
}

2

Jika Anda ingin melakukannya hanya untuk satu metode, maka nyatakan metode Anda sebagai kembali, HttpResponseMessagebukan IEnumerable<Whatever>dan lakukan:

    public HttpResponseMessage GetAllWhatever()
    {
        return Request.CreateResponse(HttpStatusCode.OK, new List<Whatever>(), Configuration.Formatters.JsonFormatter);
    }

kode ini menyakitkan untuk pengujian unit tetapi itu juga mungkin seperti ini:

    sut = new WhateverController() { Configuration = new HttpConfiguration() };
    sut.Configuration.Formatters.Add(new Mock<JsonMediaTypeFormatter>().Object);
    sut.Request = new HttpRequestMessage();

Jika Anda menginginkan sesuatu untuk suatu metode, buatlah msdn.microsoft.com/en-us/library/…
— Elisabeth


0

Yo dapat digunakan di WebApiConfig.cs:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

0

bagi mereka yang menggunakan OWIN

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

menjadi (di Startup.cs):

   public void Configuration(IAppBuilder app)
        {
            OwinConfiguration = new HttpConfiguration();
            ConfigureOAuth(app);

            OwinConfiguration.Formatters.Clear();
            OwinConfiguration.Formatters.Add(new DynamicJsonMediaTypeFormatter());

            [...]
        }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.