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.