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?

Borek Bernard
sumber
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"));
    }
}
Dmitry Pavlov
sumber
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().

Filip W
sumber
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());
        }
    }
}
JJ_Coder4Hire
sumber
9
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();

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

Bat_Programmer
sumber
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));
    }
}
Luke Puplett
sumber
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();
durilka
sumber
Jika Anda menginginkan sesuatu untuk suatu metode, buatlah msdn.microsoft.com/en-us/library/…
Elisabeth
2

Ini memiliki set tajuk yang benar. Tampak sedikit lebih elegan.

public JsonResult<string> TestMethod() 
{
return Json("your string or object");
}
Netferret
sumber
1
Apa nama yang sepenuhnya memenuhi syarat untuk kelas JsonResult dan Json?
Josh Withee
0

Yo dapat digunakan di WebApiConfig.cs:

config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
Antonio
sumber
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());

            [...]
        }
Carlo Saccone
sumber