Bagaimana cara mendapatkan ASP.NET Web API untuk mengembalikan JSON dan bukan XML menggunakan Chrome?

1220

Menggunakan ASP.NET Web API yang lebih baru , di Chrome saya melihat XML - bagaimana saya bisa mengubahnya untuk meminta JSON sehingga saya bisa melihatnya di browser? Saya yakin itu hanya bagian dari header permintaan, apakah saya benar dalam hal itu?

naspinski
sumber
8
Ada diskusi di sini untuk membuat JSON mengembalikan hanya perilaku default: github.com/aspnet/Mvc/issues/1765
Natan

Jawaban:

1738

Saya hanya menambahkan yang berikut di App_Start / WebApiConfig.cskelas dalam proyek API Web MVC saya .

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

Itu memastikan Anda mendapatkan JSON pada sebagian besar kueri, tetapi Anda bisa mendapatkannya XMLsaat Anda mengirim text/xml.

Jika Anda perlu memiliki respon Content-Typesebagai application/jsonsilahkan cek jawaban Todd bawah .

NameSpacesedang menggunakan System.Net.Http.Headers.

Felipe Leusin
sumber
115
Ini adalah jawaban yang secara mengejutkan diabaikan, dan meskipun pertanyaan aslinya tidak sepenuhnya jelas, ini secara langsung menjadikan JSON sebagai respons default untuk browser web (yang mengirimkan Accept: text / html). Kerja bagus.
gregmac
16
+1 Jauh dan jauh, jawaban terbaik. Saya membayangkan ada banyak ppl yang memilih untuk sepenuhnya menghapus XML hanya karena mereka tidak melihat JSON di browser.
Derek Hunziker
3
Saya menemukan ketika saya melakukan ini bahwa data yang disediakan oleh pihak ketiga dengan tag istirahat HTML di dalamnya berakhir dengan carriage return. JSON kemudian tidak valid. Lebih baik menggunakan jawaban yang diterima jika ini memengaruhi Anda.
Stonetip
23
Perhatikan bahwa Content-Typetajuk respons masih akan text/html.
Mrchief
78
Ini mengerikan. Header jenis konten respons haruslah aplikasi / json. "Solusi" ini membuatnya menjadi teks / html.
meffect
501

Jika Anda melakukan ini di WebApiConfigAnda akan mendapatkan JSON secara default, tetapi masih akan memungkinkan Anda untuk mengembalikan XML jika Anda lulus text/xmlsebagai Acceptheader permintaan

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);
    }
}

Jika Anda tidak menggunakan jenis proyek MVC dan karena itu tidak memiliki kelas ini untuk memulai, lihat jawaban ini untuk detail tentang cara memasukkannya.

Glenn Slaven
sumber
51
Sekadar diketahui, perilaku asli sudah benar. Chrome meminta application/xmldengan prioritas 0,9 dan */*dengan prioritas 0,8. Dengan menghapus application/xmlAnda menghapus kemampuan API Web untuk mengembalikan XML jika klien memintanya secara khusus. mis. jika Anda mengirim "Terima: aplikasi / xml" Anda masih akan menerima JSON.
porges
11
Apakah ini saya, atau apakah kalimat pertama salah? Kode ini tampaknya benar-benar menghapus XML, bukan hanya mengubah default.
NickG
6
@NickG: solusi yang diabaikan di sini dan IMHO adalah pilihan yang jauh lebih baik (menjaga aplikasi / xml) adalah solusi yang diusulkan oleh Felipe Leusin lebih rendah di halaman ini. Menggunakan config.Formatters.XmlFormatter.SupportedMediaTypes.Add (MediaTypeHeaderValue baru ("text / html"));
Cohen
1
Jadi, bagaimana kita melakukannya melalui konfigurasi web sehingga kita mendapatkan json secara default dan XML jika diminta?
Kyle
4
@Felipse Jawaban Leusin di bawah ini sebenarnya lebih pendek dan berfungsi lebih baik.
Ken Smith
314

Menggunakan RequestHeaderMapping berfungsi lebih baik, karena ia juga mengatur Content-Type = application/jsonheader respons, yang memungkinkan Firefox (dengan add-on JSONView) untuk memformat respons sebagai JSON.

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", 
                              "text/html",
                              StringComparison.InvariantCultureIgnoreCase,
                              true, 
                              "application/json"));
dmit77
sumber
6
Ini adalah solusi yang paling ramping dan paling sederhana dan Fiddler juga mendeteksi tipe konten yang dikembalikan sebagai josn.
Steve Johnson
4
Bagus! Di mana Anda menyarankan untuk meletakkan ini dalam kode?
Tim Abell
9
Itu harus masuk WebApiConfig.cs
Animesh
9
Bekerja untukku. Saya perlu menambahkan menggunakan System.Net.Http.Formatting;
bbsimonbb
1
Menautkan untuk kenyamanan saya sendiri: Jawaban ini cocok dengan langkah penyiapan lain yang biasanya saya lakukan: stackoverflow.com/a/28337589/398630 .
BrainSlugs83
309

Saya suka pendekatan Felipe Leusin yang terbaik - pastikan browser mendapatkan JSON tanpa mengurangi negosiasi konten dari klien yang benar-benar menginginkan XML. Satu-satunya bagian yang hilang bagi saya adalah bahwa header respons masih berisi tipe konten: teks / html. Mengapa itu menjadi masalah? Karena saya menggunakan ekstensi Chrome JSON Formatter , yang memeriksa tipe konten, dan saya tidak mendapatkan format cantik seperti biasa. Saya memperbaikinya dengan pemformat kustom sederhana yang menerima permintaan teks / html dan mengembalikan respons aplikasi / json:

public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
    public BrowserJsonFormatter() {
        this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        this.SerializerSettings.Formatting = Formatting.Indented;
    }

    public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType) {
        base.SetDefaultContentHeaders(type, headers, mediaType);
        headers.ContentType = new MediaTypeHeaderValue("application/json");
    }
}

Daftarkan seperti ini:

config.Formatters.Add(new BrowserJsonFormatter());
Todd Menier
sumber
24
Dalam konstruktor tambahkan this.SerializerSettings.Formatting = Formatting.Indented;jika Anda ingin itu cukup dicetak tanpa ekstensi browser.
Alastair Maw
10
mengapa Anda ingin mencetak di atas kawat?
meffect
8
Bukankah Jawaban @ dmit77 lebih baik (lebih ringkas) dari pada yang ini?
H.Wolper
8
@eddiegroves Anda tidak ingin cukup-cetak di atas kawat. Anda ingin server mengirim jumlah bit paling sedikit melalui kabel (yaitu: tanpa spasi). Kemudian Anda ingin browser memformatnya dengan baik, dengan tambahan dan semacamnya. Javascript perlu mengurai JSON biasanya, mengapa membuatnya lebih lambat dengan memperkenalkan pemformatan yang tidak perlu
meffect
13
Untuk para googler yang mencari: jangan lupa untuk menambahkan using System.Net.Http.Formattingdanusing Newtonsoft.Json
Berriel
186

MVC4 Tip Cepat # 3 – Menghapus Formatter XML dari ASP.Net Web API

Di Global.asaxtambahkan baris:

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

seperti itu:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}
Yakir Manor
sumber
9
Bekerja - jauh lebih baik memiliki JSON sebagai default daripada XML.
whitneyland
5
tetapi apakah Anda masih dapat mengembalikan xml?
Thomas Stock
99
Saya mengujinya, dan Anda tidak bisa. Jadi ini menghilangkan dukungan XML .. Anda akan diperingatkan, orang
Thomas Stock
3
Jika Anda melihat jawaban saya di bawah, ini akan membiarkan xml masih dikembalikan jika Anda mau, tetapi memungkinkan situs merespons dengan JSON ke browser
Glenn Slaven
3
@ GlennSlaven ya jawaban Anda harus yang ditandai sebagai yang benar.
radu florescu
114

Di WebApiConfig.cs , tambahkan ke akhir fungsi Daftar :

// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);

Sumber .

Michael Vashchinsky
sumber
Apakah XmlFormatter baru di MVC4?
Glenn Slaven
1
Di MVC5, ini bisa dilakukan dengan mengganti konfigurasi dengan GlobalConfiguration.Configuration
Steven
4
Untuk proyek yang harus mendukung JSON saja dan dalam keadaan apa pun tidak dapat memancarkan XML, ini adalah pilihan terbaik.
Luc C
1
config.Formatters.Add (config.Formatters.JsonFormatter);
Cas Bloem
3
Itu buruk. - Ini akan selalu mengembalikan JSON tidak peduli apa pun, bahkan jika klien secara khusus meminta XML di header Tipe-Konten.
BrainSlugs83
94

Di Global.asax saya menggunakan kode di bawah ini. URI saya untuk mendapatkan JSON adalahhttp://www.digantakumar.com/api/values?json=true

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

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

    GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new  QueryStringMapping("json", "true", "application/json"));
}
Diganta Kumar
sumber
2
Bagus Apa metode Anda mengharapkan parameter? seperti localhost: 61044 / api / values ​​/ getdate? json = true, date = 2012-08-01
LT.Nolo
apa jenis data api web kembali secara default. apakah itu json atau webapi? terima kasih
Thomas
54

Lihatlah negosiasi konten di WebAPI. Ini ( Bagian 1 & Bagian 2 ) posting blog sangat rinci dan menyeluruh menjelaskan cara kerjanya.

Singkatnya, Anda benar, dan hanya perlu mengatur Acceptatau Content-Typememinta tajuk. Mengingat Aksi Anda tidak dikodekan untuk mengembalikan format tertentu, Anda dapat mengatur Accept: application/json.

Aaron Daniels
sumber
6
"jadi saya bisa melihatnya di browser"
Spongman
1
@ Spongman, ya Anda bisa. Tetapi gunakan ekstensi seperti REST Client - sebagian besar browser menyukainya. Pengetikan langsung url di browser adalah 1. Terlalu membatasi (tidak ada kontrol atas header, tidak dapat memposting data, dll.); 2. Salah - Peramban tidak mengkonsumsi api web seperti yang dimaksudkan untuk dikonsumsi - Anda tidak dapat mengandalkannya untuk mengujinya dengan benar. Jadi, sekali lagi, add-on REST klien yang baik akan memperbaikinya.
Ivaylo Slavov
45

Karena pertanyaannya adalah khusus Chrome, Anda bisa mendapatkan ekstensi tukang pos yang memungkinkan Anda mengatur jenis konten permintaan.

Tukang pos

Chris S
sumber
Di Firefox, cukup buka about: config, cari accept.default dan ubah konten network.http.accept.defaultkonfigurasi menjadi text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7.
Bjartur Thorlacius
Atau lebih baik lagi, hanya text/html,application/xhtml+xml;q=1.0,*/*;q=0.7untuk menghindari host buggy seperti Bitbucket dari sengaja melayani browser JSON Anda sebagai pengganti HTML.
Bjartur Thorlacius
URL sudah mati. Yang baru adalah chrome.google.com/webstore/detail/postman/… .
Falcon Momot
35

Salah satu opsi cepat adalah menggunakan spesialisasi MediaTypeMapping. Berikut adalah contoh penggunaan QueryStringMapping dalam acara Application_Start:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));

Sekarang setiap kali url berisi querystring? A = b dalam hal ini, respons Json akan ditampilkan di browser.

Suhair
sumber
2
Ini sangat berguna. Anda juga dapat menggunakan UriPathExtensionMapping alih-alih QueryStringMapping jika Anda ingin menggunakan path.to/item.json
nuzzolilo
32

Kode ini menjadikan json sebagai standar saya dan memungkinkan saya untuk menggunakan format XML juga. Saya hanya akan menambahkan xml=true.

GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

Terimakasih semuanya!

jayson.centeno
sumber
1
Ini adalah jawaban yang paling fleksibel (dan benar-benar harus menjadi konfigurasi default hari ini). Untuk menambah jawaban ini, JSON adalah default, termasuk dari browser. Untuk melihat XML, tambahkan string kueri
:?
Mencoba sejumlah strategi. Punya tes sederhana untuk XML dan JSON dan ini bekerja di luar kotak
pat capozzi
23

Jangan gunakan browser Anda untuk menguji API Anda.

Alih-alih, coba gunakan klien HTTP yang memungkinkan Anda menentukan permintaan Anda, seperti CURL, atau bahkan Fiddler.

Masalah dengan masalah ini ada di klien, bukan di API. API web berperilaku dengan benar, sesuai dengan permintaan browser.

dmyoko
sumber
30
Kenapa tidak menggunakan browser? Ini adalah alat yang jelas untuk itu.
Anders Lindén
4
Saya pikir intinya di sini adalah benar dan penting - kita tidak boleh memperbaiki bagian kerja aplikasi (infrastruktur MVC WebAPI) jika masalahnya disebabkan oleh klien. Kasus penggunaan nyata untuk Api harus digunakan dengan benar (dengan menyediakan tajuk yang benar), yang merupakan tanggung jawab aplikasi. Saya tidak setuju dengan sepenuhnya membuang browser - untuk pengujian, ada banyak alat untuk hampir semua browser (Rest ekstensi seperti Klien untuk memulai dengan).
Ivaylo Slavov
6
Ini mungkin harus menjadi komentar.
bonh
17

Sebagian besar jawaban di atas masuk akal. Karena Anda melihat data diformat dalam format XML, itu artinya formatter XML diterapkan, jadi Anda dapat melihat format JSON hanya dengan menghapus XMLFormatter dari parameter HttpConfiguration seperti

public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );                
            config.Formatters.Remove(config.Formatters.XmlFormatter);                
            config.EnableSystemDiagnosticsTracing();
        }

karena JSON adalah format default

pavan kumar
sumber
12

Saya menggunakan filter tindakan global untuk menghapus Accept: application/xmlketika User-Agentheader berisi "Chrome":

internal class RemoveXmlForGoogleChromeFilter : IActionFilter
{
    public bool AllowMultiple
    {
        get { return false; }
    }

    public async Task<HttpResponseMessage> ExecuteActionFilterAsync(
        HttpActionContext actionContext,
        CancellationToken cancellationToken,
        Func<Task<HttpResponseMessage>> continuation)
    {
        var userAgent = actionContext.Request.Headers.UserAgent.ToString();
        if (userAgent.Contains("Chrome"))
        {
            var acceptHeaders = actionContext.Request.Headers.Accept;
            var header =
                acceptHeaders.SingleOrDefault(
                    x => x.MediaType.Contains("application/xml"));
            acceptHeaders.Remove(header);
        }

        return await continuation();
    }
}

Tampaknya bekerja.

Roger Lipscombe
sumber
11

Saya menemukan aplikasi Chrome "Klien Lanjutan REST" sangat bagus untuk bekerja dengan layanan REST. Anda dapat mengatur Jenis-Konten untuk application/jsonantara lain: Klien REST Lanjutan

Mike Rowley
sumber
10

Mengembalikan format yang benar dilakukan oleh formatter tipe media. Seperti yang disebutkan orang lain, Anda dapat melakukan ini di WebApiConfigkelas:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        ...

        // Configure Web API to return JSON
        config.Formatters.JsonFormatter
        .SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));

        ...
    }
}

Untuk lebih lanjut, periksa:

Jika tindakan Anda mengembalikan XML (yang merupakan kasus secara default) dan Anda hanya perlu metode khusus untuk mengembalikan JSON, Anda kemudian dapat menggunakan ActionFilterAttribute dan menerapkannya ke tindakan tertentu.

Atribut filter:

public class JsonOutputAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
    {
        ObjectContent content = actionExecutedContext.Response.Content as ObjectContent;
        var value = content.Value;
        Type targetType = actionExecutedContext.Response.Content.GetType().GetGenericArguments()[0];

        var httpResponseMsg = new HttpResponseMessage
        {
            StatusCode = HttpStatusCode.OK,
            RequestMessage = actionExecutedContext.Request,
            Content = new ObjectContent(targetType, value, new JsonMediaTypeFormatter(), (string)null)
        };

        actionExecutedContext.Response = httpResponseMsg;
        base.OnActionExecuted(actionExecutedContext);
    }
}

Berlaku untuk tindakan:

[JsonOutput]
public IEnumerable<Person> GetPersons()
{
    return _repository.AllPersons(); // the returned output will be in JSON
}

Perhatikan bahwa Anda dapat menghilangkan kata Attributepada dekorasi aksi dan menggunakan hanya [JsonOutput]sebagai gantinya [JsonOutputAttribute].

Ditumpuk
sumber
7
        config.Formatters.Remove(config.Formatters.XmlFormatter);
Gaurav Dubey
sumber
3
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban. Silakan baca stackoverflow.com/help/how-to-answer
SR
6

sesuai versi terbaru ASP.net WebApi 2,

di bawah WebApiConfig.cs, ini akan berhasil

config.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
config.Formatters.Add(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
DI
sumber
6

Tidak jelas bagi saya mengapa ada semua kompleksitas dalam jawabannya. Tentu ada banyak cara Anda bisa melakukan ini, dengan QueryStrings, header, dan opsi ... tapi apa yang saya yakini sebagai praktik terbaik itu sederhana. Anda meminta URL polos (mis .:) http://yourstartup.com/api/carsdan sebagai imbalannya Anda mendapatkan JSON. Anda mendapatkan JSON dengan tajuk respons yang tepat:

Content-Type: application/json

Dalam mencari jawaban untuk pertanyaan yang sama ini, saya menemukan utas ini, dan harus terus maju karena jawaban yang diterima ini tidak bekerja dengan tepat. Saya memang menemukan jawaban yang saya rasa terlalu sederhana untuk tidak menjadi yang terbaik:

Atur formatter WebAPI default

Saya akan menambahkan tip saya di sini juga.

WebApiConfig.cs

namespace com.yourstartup
{
  using ...;
  using System.Net.Http.Formatting;
  ...
  config.Formatters.Clear(); //because there are defaults of XML..
  config.Formatters.Add(new JsonMediaTypeFormatter());
}

Saya memang memiliki pertanyaan tentang dari mana asalnya (setidaknya yang saya lihat) berasal. Apakah mereka. NET default, atau mungkin dibuat di tempat lain (oleh orang lain di proyek saya). Bagaimanapun, semoga ini membantu.

Nick
sumber
5

Berikut adalah solusi yang mirip dengan jayson.centeno dan jawaban lainnya, tetapi menggunakan ekstensi bawaan dari System.Net.Http.Formatting.

public static void Register(HttpConfiguration config)
{
    // add support for the 'format' query param
    // cref: http://blogs.msdn.com/b/hongyes/archive/2012/09/02/support-format-in-asp-net-web-api.aspx
    config.Formatters.JsonFormatter.AddQueryStringMapping("$format", "json", "application/json");
    config.Formatters.XmlFormatter.AddQueryStringMapping("$format", "xml", "application/xml");

    // ... additional configuration
 }

Solusi ini terutama diarahkan untuk mendukung $ format untuk OData di rilis awal WebApi, tetapi juga berlaku untuk implementasi non-OData, dan mengembalikan Content-Type: application/json; charset=utf-8 header dalam respons.

Hal ini memungkinkan Anda untuk menempelkan &$format=jsonatau &$format=xmlke akhir uri Anda saat menguji dengan browser. Itu tidak mengganggu perilaku yang diharapkan lainnya saat menggunakan klien non-browser tempat Anda dapat mengatur tajuk Anda sendiri.

mdisibio
sumber
5

Anda bisa menggunakan seperti di bawah ini:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
Akshay Kapoor
sumber
Jika Anda membuat aplikasi WebAPI hanya untuk mengirimkan pesan JSON, pertimbangkan jawaban ini.
allen1
4

Cukup tambahkan dua baris kode di kelas WebApiConfig Anda

public static class WebApiConfig
{
     public static void Register(HttpConfiguration config)
     {
          //add this two line 
          config.Formatters.Clear();
          config.Formatters.Add(new JsonMediaTypeFormatter());


          ............................
      }
}
Md. Sabbir Ahamed
sumber
3

Anda baru saja mengubah App_Start/WebApiConfig.csseperti ini:

public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services

        // Web API routes
        config.MapHttpAttributeRoutes();
        //Below formatter is used for returning the Json result.
        var appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
        config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
        //Default route
        config.Routes.MapHttpRoute(
           name: "ApiControllerOnly",
           routeTemplate: "api/{controller}"
       );
    }
vaheeds
sumber
Menghapus formatter umumnya bukan ide yang baik, Anda menghapus fungsionalitas.
naspinski
Sebenarnya dalam kasus ini, ini bekerja dengan baik untuk saya, juga banyak orang lain menyarankan cara seperti ini. Saya telah mempelajarinya dari buku myview.rahulnivi.net/building-spa-angular-mvc-5 !
vaheeds
2

Dari MSDN, Membangun Aplikasi Halaman Tunggal dengan ASP.NET dan AngularJS (sekitar 41 menit).

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // ... possible routing etc.

        // Setup to return json and camelcase it!
        var formatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
        formatter.SerializerSettings.ContractResolver =
            new Newtonsoft.Json.Serialization.CamelCasePropertyNamesContractResolver();
    }

Seharusnya saat ini, saya mencobanya dan berhasil.

lko
sumber
2

Beberapa waktu telah berlalu sejak pertanyaan ini ditanyakan (dan dijawab) tetapi opsi lain adalah menimpa header Terima di server selama pemrosesan permintaan menggunakan MessageHandler seperti di bawah ini:

public class ForceableContentTypeDelegationHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
    {
        var someOtherCondition = false;
        var accHeader = request.Headers.GetValues("Accept").FirstOrDefault();
        if (someOtherCondition && accHeader.Contains("application/xml"))
        {
            request.Headers.Remove("Accept");
            request.Headers.Add("Accept", "application/json");
        }
        return await base.SendAsync(request, cancellationToken);
    }
}

Di mana someOtherConditionbisa apa saja termasuk tipe peramban, dll. Ini akan menjadi kasus bersyarat di mana hanya kadang-kadang kita ingin mengganti negosiasi konten default. Kalau tidak sesuai jawaban lain, Anda hanya akan menghapus formatter yang tidak perlu dari konfigurasi.

Anda harus mendaftarkannya, tentu saja. Anda dapat melakukan ini secara global:

  public static void Register(HttpConfiguration config) {
      config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
  }

atau berdasarkan rute dengan rute:

config.Routes.MapHttpRoute(
   name: "SpecialContentRoute",
   routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
   defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
   constraints: null,
   handler: new ForceableContentTypeDelegationHandler()
);

Dan karena ini adalah penangan pesan, pesan itu akan berjalan baik pada permintaan dan respons ujung pipa seperti sebuah HttpModule. Jadi, Anda dapat dengan mudah mengakui penggantian dengan tajuk khusus:

public class ForceableContentTypeDelegationHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
                HttpRequestMessage request,
                CancellationToken cancellationToken)
    {
        var wasForced = false;
        var someOtherCondition = false;
        var accHeader = request.Headers.GetValues("Accept").FirstOrDefault();
        if (someOtherCondition && accHeader.Contains("application/xml"))
        {
            request.Headers.Remove("Accept");
            request.Headers.Add("Accept", "application/json");
            wasForced = true;
        }

        var response =  await base.SendAsync(request, cancellationToken);
        if (wasForced){
          response.Headers.Add("X-ForcedContent", "We overrode your content prefs, sorry");
        }
        return response;
    }
}
rism
sumber
2

Ini adalah cara termudah yang saya gunakan dalam aplikasi saya. Tambahkan diberikan di bawah 3 baris kode App_Start\\WebApiConfig.csdalam Registerfungsi

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

    config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));

Asp.net web API akan secara otomatis membuat serial objek Anda yang kembali ke JSON dan seperti yang application/jsonditambahkan di header sehingga browser atau penerima akan memahami bahwa Anda mengembalikan hasil JSON.

Vikas Bansal
sumber
1

WebApiConfig adalah tempat di mana Anda dapat mengkonfigurasi apakah Anda ingin menghasilkan json atau xml. secara default xml. dalam fungsi register kita dapat menggunakan HttpConfiguration Formatters untuk memformat output. System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") diperlukan untuk mendapatkan output dalam format json. masukkan deskripsi gambar di sini

rocky_pps
sumber
1

Menggunakan jawaban Felipe Leusin selama bertahun-tahun, setelah pembaruan terbaru dari perpustakaan inti dan Json.Net, saya bertemu dengan System.MissingMethodException: SupportedMediaTypes. Solusi dalam kasus saya, semoga bermanfaat bagi orang lain yang mengalami pengecualian tak terduga yang sama, adalah menginstal System.Net.Http. NuGet tampaknya menghapusnya dalam beberapa keadaan. Setelah instalasi manual, masalah terselesaikan.

Charles Burns
sumber
-3

Saya heran melihat begitu banyak balasan yang memerlukan pengkodean untuk mengubah penggunaan tunggal (GET) dalam satu API alih-alih menggunakan alat yang tepat apa yang harus diinstal sekali dan dapat digunakan untuk API apa pun (milik sendiri atau pihak ketiga) dan semua gunakan kasing.

Jadi jawabannya adalah:

  1. Jika Anda hanya ingin meminta json atau jenis konten lain, instal Requestly atau alat serupa dan ubah tajuk Terima.
  2. Jika Anda ingin menggunakan POST juga dan telah dengan baik memformat json, xml, dll. Gunakan ekstensi pengujian API yang tepat seperti Postman atau ARC .
pengguna3285954
sumber
Beberapa lebih suka melakukan hal-hal tanpa menambahkan mengasapi dalam bentuk alat dan perpustakaan tambahan.
tno2007
Masih salah untuk membuat perubahan pada API hanya karena seseorang menggunakan alat yang salah untuk pekerjaan itu. Peramban web tidak dirancang untuk menguji API, bahkan untuk melihat output dari API tetapi untuk melihat dokumen. Lebih buruk lagi jika seseorang berpikir alat penguji API adalah mengasapi bukan bagian dari perangkat wajib untuk pengembang API, dan jujur ​​saya akan menambahkan pengembang ujung depan juga karena mereka perlu berinteraksi dan bereksperimen dengan API juga. Ini juga mungkin tidak cukup karena browser tanpa addins tidak memungkinkan untuk mengatur header, memposting ke API atau bahkan memeriksa header respons.
user3285954
Saya mengerti apa yang Anda katakan dan Anda tidak salah. Tapi di luar topik, alasan mengapa Anda terpilih adalah nada di mana Anda menjawab pertanyaan. Anda terdengar sangat agresif dan tampil sebagai pengembang yang berpikir mereka tahu segalanya, dan itu sangat tidak menyenangkan. Saya yakin Anda adalah pengembang yang hebat, menilai dari tanggapan Anda. Tapi, Anda harus belajar, terutama di lingkungan QA profesional seperti ini, untuk mengatasi dan meyakinkan orang dengan cara yang lebih ramah dan lebih manusiawi. Mungkin, pertama berikan jawaban yang mereka inginkan, kemudian jelaskan cara yang lebih baik, dan motivasi mengapa itu lebih baik.
tno2007