ASP.NET Web API'sini Chrome kullanarak XML yerine JSON döndürmesini nasıl sağlayabilirim?


1220

Yeni Kullanarak ASP.NET Web API içinde, Krom I XML görüyorum - nasıl istemek için değiştirebilirsiniz JSON ben tarayıcıda görüntüleyebilmek için? Bunun sadece istek başlıklarının bir parçası olduğuna inanıyorum, bu konuda doğru muyum?


8
Burada JSON'u
Natan

Yanıtlar:


1737

Ben sadece App_Start / WebApiConfig.csMVC Web API projeme sınıfta aşağıdaki ekleyin .

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

Bu, çoğu sorguda JSON almanızı sağlar, ancak XMLgönderdiğinizde alabilirsiniz text/xml.

Eğer cevabı almanız gerekiyorsa Content-Type, application/jsonlütfen Todd'un cevabını aşağıdan kontrol edin .

NameSpacekullanıyor System.Net.Http.Headers.


115
Bu şaşırtıcı bir şekilde gözden kaçan bir yanıttır ve orijinal soru tamamen açık olmasa da, bu doğrudan JSON'u bir web tarayıcısı için varsayılan yanıt yapar (Kabul: metin / html gönderir). Aferin.
gregmac

16
+1 Uzak ve uzak en iyi cevap. Tarayıcıda JSON görmedikleri için XML'i tamamen kaldırmayı tercih eden bir ton ppl olduğunu hayal ediyorum.
Derek Hunziker

3
Bunu yaptığımda, içinde HTML sonu etiketleri olan üçüncü bir tarafça sağlanan verilerin, satır başı ile sonuçlandığını buldum. JSON daha sonra geçersizdi. Bu sizi etkiliyorsa kabul edilen cevabı kullanmak daha iyidir.
Stonetip

23
Yanıt Content-Typeverenin üstbilgisinin yine de kalacağını unutmayın text/html.
Mrchief

78
Bu korkunç. Yanıt içerik türü üstbilgisi application / json olmalıdır. Bu "çözüm" metni / html yapar.
meffect

501

Bunu yaparsanız WebApiConfig, varsayılan olarak JSON alırsınız, ancak text/xmlistek Acceptüstbilgisi olarak geçerseniz XML döndürmenize izin verir.

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

MVC proje türünü kullanmıyorsanız ve bu nedenle başlangıçta bu sınıfa sahip değilseniz , nasıl dahil edileceğiyle ilgili ayrıntılar için bu cevaba bakın .


51
Sadece not etmek gerekirse, orijinal davranış doğrudur. application/xml0,9 */*önceliği ve 0,8 önceliği olan Chrome istekleri . application/xmlWeb API'sini kaldırarak istemci özel olarak isterse XML döndürme yeteneğini kaldırırsınız. Örneğin "Accept: application / xml" gönderirseniz yine de JSON alırsınız.
Mart'ta

11
Benim mi, yoksa ilk cümle yanlış mı? Kod, varsayılanı değiştirmekle kalmaz, XML'i tamamen kaldırmış gibi görünür.
NickG

6
@NickG: Burada gözden kaçan bir çözüm ve IMHO çok daha iyi bir seçenektir (application / xml tutmak) bu sayfada Felipe Leusin tarafından önerilen çözümdür. Config.Formatters.XmlFormatter.SupportedMediaTypes.Add (new MediaTypeHeaderValue ("text / html"));
Cohen

1
Öyleyse, web yapılandırması yoluyla bunu nasıl yaparız, böylece istendiğinde varsayılan olarak json ve XML alırız?
Kyle

4
@Felipse Leusin'in aşağıdaki cevabı aslında daha kısadır ve daha iyi çalışır.
Ken Smith

313

RequestHeaderMapping kullanımı daha da iyi çalışır, çünkü Content-Type = application/jsonFirefox'un (JSONView eklentisi ile) yanıtı JSON olarak biçimlendirmesine izin veren yanıt başlığında da ayarlar .

GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept", 
                              "text/html",
                              StringComparison.InvariantCultureIgnoreCase,
                              true, 
                              "application/json"));

6
Bu en yalın ve en basit çözümdür ve Fiddler ayrıca josn olarak döndürülen içerik türünü de algılar.
Steve Johnson

4
Güzel! Bunu koda nereye koymanızı önerirsiniz?
Tim Abell

9
WebApiConfig.cs
Animesh

9
Benim için çalıştı. Kullanarak System.Net.Http.Formatting
bbsimonbb

1
Kendi rahatlığım için bağlantı: Bu cevap genellikle gerçekleştirdiğim başka bir kurulum adımıyla güzelce oynar: stackoverflow.com/a/28337589/398630 .
BrainSlugs83

308

Felipe Leusin'in yaklaşımını en çok seviyorum - tarayıcıların aslında XML isteyen istemcilerden içerik anlaşmasından ödün vermeden JSON aldığından emin olun. Benim için tek eksik parça, yanıt başlıklarının hala content-type: text / html içermesi idi. Bu neden bir problemdi? Çünkü içerik türünü inceleyen JSON Formatter Chrome uzantısını kullanıyorum ve alıştığım güzel biçimlendirmeyi alamıyorum. Metin / html isteklerini kabul eden ve application / json yanıtları döndüren basit bir özel biçimlendirici ile düzelttim:

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

Şu şekilde kaydolun:

config.Formatters.Add(new BrowserJsonFormatter());

24
Yapıcıda, this.SerializerSettings.Formatting = Formatting.Indented;tarayıcı uzantısı olmadan güzel yazdırılmasını istiyorsanız ekleyin .
Alastair Maw

10
neden tel üzerinden güzel baskı yapmasını istesin ki?
meffect

8
@ Dmit77 adlı kullanıcının cevabı bundan daha iyi (daha özlü) değil mi?
H.Wolper

8
@eddiegroves tel üzerinden güzel baskı istemiyorum. Sunucunun tel üzerinden en az miktarda bit göndermesini istiyorsunuz (yani: boşluk yok). Sonra tarayıcının eklentiler ve benzeri ile güzel bir şekilde biçimlendirmesini istiyorsunuz. Javascript genellikle JSON ayrıştırmak gerekiyor, neden gereksiz biçimlendirme tanıtarak yavaşlatmak gerekir
meffect

13
Arayan Google çalışanları için: eklemeyi unutma using System.Net.Http.Formattingveusing Newtonsoft.Json
Berriel

186

MVC4 Hızlı İpucu # 3 – XML Formatter'ı ASP.Net Web API'sinden Kaldırma

Gelen Global.asaxsatırı ekleyin:

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

şöyle:

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

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

    BundleTable.Bundles.RegisterTemplateBundles();
    GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}

9
Works - XML ​​yerine varsayılan JSON olması çok daha hoş.
whitneyland

5
ama yine de xml döndürebilir misin?
Thomas Stock

99
Test ettim ve yapamazsın. Bu XML desteğini kaldırıyor .. Dikkatli olun, sevgili google insanları
Thomas Stock

3
Aşağıdaki yanıta bir göz attıysanız, bu isterseniz xml'nin hala döndürülmesine izin verir, ancak sitenin JSON ile tarayıcıya yanıt vermesine izin verir
Glenn Slaven

3
@GlennSlaven evet cevabınız doğru olarak işaretlenmiş cevap olmalıdır.
radu florescu

114

Gelen WebApiConfig.cs , sonuna eklenecek Kayıt fonksiyonu:

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

Kaynak .


MVC4'te XmlFormatter yeni mi?
Glenn Slaven

1
MVC5'te bu, yapılandırmayı GlobalConfiguration ile değiştirerek yapılabilir.Configuration
Steven

4
Yalnızca JSON'u desteklemesi gereken ve hiçbir koşulda XML yayınlamasına izin verilemeyen bir proje için bu en iyi seçenektir.
Luc C

1
config.Formatters.Add (config.Formatters.JsonFormatter);
Cas Bloem

3
Bu korkunç. - İstemci özellikle İçerik Türü üstbilgisinde XML istemiş olsa bile, bu ne olursa olsun her zaman JSON döndürür.
BrainSlugs83

94

In Global.asax ben aşağıdaki kodu kullanıyorum. JSON almak için URI'mhttp://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"));
}

2
Muhteşem bir tane. Metodunuz bir parametre bekliyor mu? localhost
LT.Nolo

web api veri biçimi varsayılan olarak ne tür bir dönüş. json veya webapi mi? teşekkürler
Thomas

54

WebAPI'deki içerik pazarlamasına göz atın. Bu ( Bölüm 1 ve Bölüm 2 ) harika ayrıntılı ve kapsamlı blog gönderileri nasıl çalıştığını açıklar.

Kısacası haklısınız ve üstbilgileri ayarlamanız Acceptveya Content-Typeistemeniz yeterli. İşleminizin belirli bir biçimi döndürecek şekilde kodlanmadığı göz önüne alındığında, ayarlayabilirsiniz Accept: application/json.


6
"böylece tarayıcıda görebilirsiniz"
Spongman

1
@Spongman, evet yapabilirsin. Ancak REST İstemcisi gibi bir uzantı kullanın - çoğu tarayıcıda buna benzer bir uzantı vardır. Bir tarayıcıda url'nin doğrudan yazılması 1'dir. Çok sınırlayıcı (başlıklar üzerinde kontrol yok, veri gönderemez vb.); 2. Hatalı - Tarayıcı, web API'sini tüketilmesi amaçlandığı gibi tüketmez - düzgün bir şekilde test etmesine güvenemezsiniz. Yani, yine, iyi bir REST istemci eklentisi bunu düzeltir.
Ivaylo Slavov

45

Soru Chrome'a ​​özgü olduğundan, istek içerik türünü ayarlamanızı sağlayan Postacı uzantısını alabilirsiniz .

postacı


Firefox'ta, yaklaşık: config adresine gidin, accept.default öğesini arayın ve network.http.accept.defaultyapılandırmanın içeriğini olarak değiştirin text/html,application/xhtml+xml,application/json;q=0.9,application/xml;q=0.8,*/*;q=0.7.
Bjartur Thorlacius

Ya da daha iyisi, text/html,application/xhtml+xml;q=1.0,*/*;q=0.7Bitbucket gibi buggy ana bilgisayarlarının yanlışlıkla HTML yerine tarayıcınızın JSON'una hizmet etmesini önlemek için.
Bjartur Thorlacius


35

Hızlı seçeneklerden biri MediaTypeMapping uzmanlığını kullanmaktır. Application_Start olayında QueryStringMapping kullanımına bir örnek:

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

Şimdi url bu durumda? A = b sorgusu içerdiğinde, tarayıcıda Json yanıtı gösterilecektir.


2
Bu çok faydalı oldu. Path.to/item.json
nuzzolilo 13:12

32

Bu kod json'u benim varsayılanım yapıyor ve XML formatını da kullanmama izin veriyor. Sadece ekleyeceğim xml=true.

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

Herkese teşekkürler!


1
Bu en esnek yanıttır (ve bu günlerde gerçekten varsayılan yapılandırma olmalıdır). Bu yanıta eklemek için tarayıcıdan dahil varsayılan değer JSON'dir. XML'yi görüntülemek için sorgu dizesi ekleyin
:?

Bir dizi strateji denedim. XML ve JSON için basit bir test
yaptık

23

API'nizi test etmek için tarayıcınızı kullanmayın.

Bunun yerine, CURL ve hatta Fiddler gibi isteğinizi belirtmenize izin veren bir HTTP istemcisi kullanmayı deneyin.

Bu sorunla ilgili sorun API'da değil istemcide. Web API'si, tarayıcının isteğine göre doğru şekilde çalışır.


30
Neden tarayıcıyı kullanmıyorsunuz? Bunun için bariz bir araçtır.
Anders Lindén

4
Bence buradaki nokta doğru ve önemli - sorunun istemciden kaynaklanması durumunda uygulamanın (MVC WebAPI altyapısı) çalışan bir bölümünü geçersiz kılmamalıyız. Bir Api'nin gerçek kullanım durumu, uygulamanın sorumluluğu olan (doğru başlıklar sağlayarak) düzgün bir şekilde kullanılmalıdır. Tarayıcıyı tamamen atmaya katılmıyorum - test etmek için hemen hemen her tarayıcı için çok sayıda araç var (Başlamak için İstemci benzeri uzantıların geri kalanı).
Ivaylo Slavov

6
Bu muhtemelen bir yorum olmalı.
bonh

17

Yukarıdaki cevapların çoğu mükemmel mantıklı. Verilerin XML biçiminde biçimlendirildiğini gördüğünüz için, bu XML biçimlendiricinin uygulandığı anlamına gelir, SO, JSFor biçimini yalnızca XMLFormatter'ı HttpConfiguration parametresinden aşağıdaki gibi kaldırarak görebilirsiniz.

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

JSON varsayılan biçim olduğundan


12

Ben kaldırmak için küresel bir eylem filtresi kullanıldığında Accept: application/xmlzaman User-Agentbaşlığı "Chrome" içerir:

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

Çalışıyor gibi görünüyor.


11

Chrome uygulaması "Gelişmiş REST İstemcisi" ni REST hizmetleriyle çalışmak için mükemmel buldum. İçerik Türü'nü application/jsondiğer özelliklerin yanı sıra ayarlayabilirsiniz : Advanced REST client


10

Doğru formatın döndürülmesi ortam tipi formatlayıcı tarafından yapılır. Diğerlerinin de belirttiği gibi, bunu WebApiConfigsınıfta yapabilirsiniz:

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

        ...
    }
}

Daha fazla bilgi için şunları kontrol edin:

İşlemlerinizin XML döndürmesi durumunda (varsayılan olarak durum budur) ve JSON'u döndürmek için yalnızca belirli bir yönteme ihtiyacınız varsa, daha sonra bir öğesini kullanabilir ActionFilterAttributeve söz konusu eyleme uygulayabilirsiniz.

Filtre özelliği:

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

Eyleme başvurma:

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

AttributeEylem dekorasyonundaki kelimeyi atlayabileceğinizi ve [JsonOutput]bunun yerine kullanabileceğinizi unutmayın [JsonOutputAttribute].


7
        config.Formatters.Remove(config.Formatters.XmlFormatter);

3
Bu kod soruyu cevaplayabilirken, sorunun nasıl ve / veya neden çözüldüğüne dair ek bağlam sağlamak yanıtlayıcının uzun vadeli değerini artıracaktır. Lütfen bu stackoverflow.com/help/how-to-answer
SR

6

ASP.net WebApi 2'nin son sürümüne göre,

altında WebApiConfig.cs, bu işe yarayacak

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

6

Cevapta neden tüm bu karmaşıklığın olduğu açık değil. Elbette bunu QueryStrings, başlıklar ve seçeneklerle yapabileceğiniz birçok yol var ... ama en iyi uygulama olduğuna inandığım şey basit. Düz bir URL (ör http://yourstartup.com/api/cars:) istersiniz ve karşılığında JSON alırsınız. JSON'u uygun yanıt üstbilgisiyle alırsınız:

Content-Type: application/json

Bu aynı soruya bir cevap ararken, bu konuyu buldum ve devam etmek zorunda kaldı çünkü bu kabul edilen cevap tam olarak çalışmıyor. En iyisi olamayacak kadar basit olduğunu düşündüğüm bir cevap buldum:

Varsayılan WebAPI biçimlendiricisini ayarlama

Buraya ipucumu da ekleyeceğim.

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

Varsayılanların (en azından gördüğüm) nereden geldiğine dair bir sorum var. .NET varsayılanları mı yoksa belki de başka bir yerde mi (projemdeki başka biri tarafından) oluşturulmuşlar. Her neyse, umarım bu yardımcı olur.


5

İşte jayson.centeno ve diğer cevaplara benzer , ancak dahili uzantıyı kullanarak bir çözüm 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
 }

Çözüm, öncelikle WebApi'nin ilk sürümlerinde OData için $ biçimini desteklemeye yönelikti, ancak OData dışı uygulama için de geçerlidir Content-Type: application/json; charset=utf-8ve yanıttaki başlığı döndürür .

Bir tarayıcı ile test ederken uranızın yapışmasını &$format=jsonveya &$format=xmlsonuna kadar yapmanızı sağlar . Kendi başlıklarınızı ayarlayabileceğiniz tarayıcı dışı bir istemci kullanırken diğer beklenen davranışlarla etkileşime girmez.


5

Aşağıdaki gibi kullanabilirsiniz:

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

Sadece JSON mesajlarını ilettiğiniz için bir WebAPI uygulaması yapıyorsanız, bu yanıtı göz önünde bulundurun.
allen1

4

Bu iki kod satırını WebApiConfig sınıfınıza eklemeniz yeterlidir

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


          ............................
      }
}

3

Sadece şu şekilde değiştirirsiniz App_Start/WebApiConfig.cs:

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

Bir biçimlendiriciyi kaldırmak genellikle iyi bir fikir değildir, işlevselliği kaldırıyorsunuzdur.
naspinski

Aslında bu durumda, benim için iyi çalışıyor, diğerleri de böyle bir yol öneriyor. Bunu myview.rahulnivi.net/building-spa-angular-mvc-5 kitabından öğrendim !
vaheeds

2

Gönderen MSDN Building ASP.NET ve angularjs ile Tek Sayfa Uygulama (41 dakika yaklaşık olarak).

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

Güncel olmalı, denedim ve işe yaradı.


2

Bu soru sorulduğundan (ve yanıtlandığından) biraz zaman geçti, ancak başka bir seçenek, aşağıdaki gibi bir MessageHandler kullanarak istek işleme sırasında sunucudaki Kabul üstbilgisini geçersiz kılmaktır:

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

someOtherConditionTarayıcı türü vb. Dahil olmak üzere herhangi bir şey nerede olabilir. Bu, yalnızca bazen varsayılan içerik anlaşmasını geçersiz kılmak istediğimiz koşullu durumlar için olacaktır. Aksi takdirde, diğer yanıtlara göre, gereksiz bir biçimlendiriciyi yapılandırmadan kaldırmanız yeterlidir.

Elbette kaydetmeniz gerekecek. Bunu global olarak yapabilirsiniz:

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

veya rota bazında rota üzerinde:

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

Ve bu bir mesaj işleyici olduğundan, boru hattının hem istek hem de yanıt uçlarında bir HttpModule. Böylece, özel bir başlık ile geçersiz kılmayı kolayca onaylayabilirsiniz:

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

2

İşte uygulamalarımda kullandığım en kolay yol. Kod 3 hatları aşağıda verilmiştir Ekle App_Start\\WebApiConfig.csyılında Registerfonksiyonu

    var formatters = GlobalConfiguration.Configuration.Formatters;

    formatters.Remove(formatters.XmlFormatter);

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

Asp.net web API, dönen nesnenizi otomatik olarak JSON'a serileştirir application/jsonve başlığa eklenirken tarayıcı veya alıcı JSON sonucunu döndürdüğünüzü anlar.


1

WebApiConfig, json veya xml olarak çıktı almak isteyip istemediğinizi yapılandırabileceğiniz yerdir. varsayılan olarak xml'dir. register fonksiyonunda çıktıyı biçimlendirmek için HttpConfiguration Formatters'ı kullanabiliriz. Çıktıyı json formatında almak için System.Net.Http.Headers => MediaTypeHeaderValue ("text / html") gereklidir. resim açıklamasını buraya girin


1

Kullanılması Felipe Leusin çekirdek kütüphanelerin ve Json.NET bir son güncellemeden sonra, yıllardır cevabını, ben koştum System.MissingMethodExceptionSupportedMediaTypes:. Benim durumumda, aynı beklenmedik istisnayı yaşayan başkalarına yardımcı olan çözüm yüklemek System.Net.Http. NuGet bazı durumlarda onu kaldırıyor. Manuel kurulumdan sonra sorun çözüldü.


-3

Ben bir tek kullanımlık durumda (GET) değiştirmek için kodlama gerektiren pek çok cevap görmek şaşırtmıştır ediyorum bir API yerine bir kere kurulacak ve kullanılabilir ne uygun araç kullanarak herhangi tüm API (kendi veya 3. taraf) ve kullanım örnekleri.

Yani iyi cevap:

  1. Yalnızca json veya başka bir içerik türü istemek istiyorsanız, Requestly veya benzer bir araç yükleyin ve Kabul üstbilgisini değiştirin.
  2. POST'u da kullanmak ve güzel biçimlendirilmiş json, xml vb. Varsa, Postman veya ARC gibi uygun bir API test uzantısı kullanın .

Bazıları ekstra araçlar ve kütüphaneler şeklinde şişkinlik yapmadan bir şeyler yapmayı tercih eder.
tno2007

API'da değişiklik yapmak hala yanlıştır, çünkü birisi iş için yanlış aracı kullanıyor. Bir web tarayıcısı, API'leri test etmek için tasarlanmamıştır, API'ların çıktısını görüntülemek için değil, belgeleri görüntülemek için bile. Birisi herhangi bir API geliştiricisi için zorunlu araç setinin bir parçası yerine bir API test aracı aracı şişkin olduğunu düşünüyorsa daha da kötüsü ve dürüst olmak gerekirse, API'larla da etkileşimde bulunmaları ve deney yapmaları gerektiğinden ön uç geliştiricileri de ekleyeceğim. Ayrıca muhtemelen yeterli değildir çünkü eklentileri olmayan tarayıcı üstbilgileri ayarlamaya, bir API'ye yayın göndermeye ve hatta yanıt üstbilgilerini incelemeye izin vermez.
user3285954

Ne dediğini anlıyorum ve yanlış değilsin. Ancak konu dışı, aşağı oy vermenizin nedeni, soruyu cevapladığınız tondur. Çok kavgacı geliyor ve her şeyi bildiğini düşünen geliştirici olarak karşınıza çıkıyor ve bu çok tatsız. Yanıtlarınıza bakarak harika bir geliştirici olduğunuzdan eminim. Ancak, özellikle böyle profesyonel bir KG ortamında, insanlara daha dostça ve daha insani bir şekilde hitap etmeyi ve ikna etmeyi öğrenmelisiniz. Belki de önce istedikleri cevabı verin, sonra daha iyi bir yol açıklayın ve neden daha iyi olduğunu motive edin.
tno2007
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.