Yanıtlar:
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.
Content-Typeverenin üstbilgisinin yine de kalacağını unutmayın text/html.
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 .
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.
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"));
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());
this.SerializerSettings.Formatting = Formatting.Indented;tarayıcı uzantısı olmadan güzel yazdırılmasını istiyorsanız ekleyin .
using System.Net.Http.Formattingveusing Newtonsoft.Json
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();
}
Gelen WebApiConfig.cs , sonuna eklenecek Kayıt fonksiyonu:
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
Kaynak .
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"));
}
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.
Soru Chrome'a özgü olduğundan, istek içerik türünü ayarlamanızı sağlayan Postacı uzantısını alabilirsiniz .

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.
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.
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.
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!
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.
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
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.
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
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].
config.Formatters.Remove(config.Formatters.XmlFormatter);
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.
İş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.
Aşağıdaki gibi kullanabilirsiniz:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
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());
............................
}
}
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}"
);
}
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ı.
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;
}
}
İş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.
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.

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ü.
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: