回答:
App_Start / WebApiConfig.cs
MVC Web APIプロジェクトのクラスに次のコードを追加するだけです。
config.Formatters.JsonFormatter.SupportedMediaTypes
.Add(new MediaTypeHeaderValue("text/html") );
これにより、ほとんどのクエリでJSONが確実に取得されますがXML
、を送信すると取得できますtext/xml
。
応答が必要な場合は、以下のトッドの回答を確認しContent-Type
てapplication/json
ください。
NameSpace
が使用していSystem.Net.Http.Headers
ます。
Content-Type
ヘッダーは引き続きであることに注意してくださいtext/html
。
でこれを行うと、WebApiConfig
デフォルトでJSONを取得しますがtext/xml
、リクエストAccept
ヘッダーとして渡すと、XMLを返すことができます。
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プロジェクトタイプを使用していないため、このクラスが最初からなかった場合は、この回答を組み込んで、その組み込み方法の詳細を確認してください。
application/xml
優先度0.9および*/*
優先度0.8のChromeリクエスト。削除するapplication/xml
と、クライアントが特に要求した場合にWeb APIがXMLを返す機能が削除されます。たとえば、「Accept:application / xml」を送信した場合でも、JSONを受信します。
RequestHeaderMappingを使用するContent-Type = application/json
と、応答ヘッダーにもが設定され、Firefox(JSONViewアドオンを使用)が応答をJSONとしてフォーマットできるようになるため、さらにうまく機能します。
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings
.Add(new System.Net.Http.Formatting.RequestHeaderMapping("Accept",
"text/html",
StringComparison.InvariantCultureIgnoreCase,
true,
"application/json"));
好き Felipe Leusinのアプローチが一番です。実際にXMLを必要とするクライアントからのコンテンツネゴシエーションを損なうことなく、ブラウザーがJSONを確実に取得できるようにしてください。私にとって唯一欠けていたのは、応答ヘッダーにまだcontent-type:text / htmlが含まれていることでした。なぜそれが問題でしたか?私が使用しているのは、コンテンツタイプを検査するJSON Formatter Chrome拡張機能を使用しているためです。text / htmlリクエストを受け入れ、application / 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");
}
}
次のように登録します。
config.Formatters.Add(new BrowserJsonFormatter());
this.SerializerSettings.Formatting = Formatting.Indented;
、ブラウザ拡張なしできれいに印刷したい場合は追加します。
using System.Net.Http.Formatting
を忘れないでくださいusing Newtonsoft.Json
MVC4クイックヒント#3-ASP.Net Web APIからのXMLフォーマッターの削除
でGlobal.asax
行を追加します。
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
そのようです:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
BundleTable.Bundles.RegisterTemplateBundles();
GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
}
でWebApiConfig.cs、の末尾に追加登録機能:
// Remove the XML formatter
config.Formatters.Remove(config.Formatters.XmlFormatter);
ソース。
Global.asaxでは、以下のコードを使用しています。JSONを取得するための私のURIはhttp://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のコンテンツネゴシエーションをご覧ください。これら(パート1とパート2)は、驚くほど詳細で完全なブログ投稿で、その仕組みを説明しています。
要するに、あなたは正しいです、Accept
またはContent-Type
要求ヘッダーを設定する必要があるだけです。アクションが特定の形式を返すようにコーディングされていない場合は、を設定できますAccept: application/json
。
質問はChrome固有なので、リクエストのコンテンツタイプを設定できるPostman拡張機能を入手できます。
network.http.accept.default
設定の内容をに変更します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.7
、BitbucketなどのバグのあるホストがHTMLの代わりにブラウザーのJSONを誤って提供しないようにするためです。
簡単なオプションの1つは、MediaTypeMapping特殊化を使用することです。Application_StartイベントでQueryStringMappingを使用する例を次に示します。
GlobalConfiguration.Configuration.Formatters.JsonFormatter.MediaTypeMappings.Add(new QueryStringMapping("a", "b", "application/json"));
この場合、URLにクエリ文字列?a = bが含まれている場合は常に、ブラウザーにJson応答が表示されます。
このコードにより、jsonがデフォルトになり、XML形式も使用できるようになります。追加するだけxml=true
です。
GlobalConfiguration.Configuration.Formatters.XmlFormatter.MediaTypeMappings.Add(new QueryStringMapping("xml", "true", "application/xml"));
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
みんな、ありがとう!
APIのテストにブラウザーを使用しないでください。
代わりに、CURLやFiddlerなどのリクエストを指定できるHTTPクライアントを使用してみてください。
この問題の問題は、APIではなくクライアントにあります。ブラウザの要求に従って、Web APIは正しく動作します。
上記の答えのほとんどは完全に理にかなっています。データがXML形式でフォーマットされていることがわかります。つまり、XMLフォーマッターが適用されているので、次のようにHttpConfigurationパラメーターからXMLFormatterを削除するだけでJSON形式を確認できます。
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がデフォルトのフォーマットなので
ヘッダーに「Chrome」が含まれているAccept: application/xml
場合は、グローバルアクションフィルターを使用して削除しましたUser-Agent
。
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();
}
}
動作するようです。
Chromeサービス「Advanced REST Client」は、RESTサービスとの連携に優れていることがわかりました。Content-Typeを次のように設定できますapplication/json
:
Advanced REST client
正しい形式を返すのは、メディアタイプフォーマッタによって行われます。他の人が述べたように、あなたはWebApiConfig
クラスでこれを行うことができます:
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"));
...
}
}
詳細については、次を確認してください。
アクションがXMLを返す場合(これはデフォルトです)、JSONを返すために特定のメソッドのみが必要な場合、を使用ActionFilterAttribute
してその特定のアクションに適用できます。
フィルター属性:
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);
}
}
アクションへの適用:
[JsonOutput]
public IEnumerable<Person> GetPersons()
{
return _repository.AllPersons(); // the returned output will be in JSON
}
Attribute
アクションの装飾で単語を省略して、の[JsonOutput]
代わりに使用できることに注意してください[JsonOutputAttribute]
。
config.Formatters.Remove(config.Formatters.XmlFormatter);
なぜこの複雑さがすべて答えにあるのかは不明です。確かに、QueryString、ヘッダー、オプションを使用してこれを行う方法はたくさんありますが、私がベストプラクティスであると私が信じているのは簡単です。プレーンURL(例:)をリクエストするhttp://yourstartup.com/api/cars
と、JSONが返されます。適切な応答ヘッダーを含むJSONを取得します。
Content-Type: application/json
このまったく同じ質問への回答を探す際に、私はこのスレッドを見つけました。この受け入れられた回答が正確に機能しないため、続行しなければなりませんでした。私は、あまりにも単純すぎて最高の答えにはならないと思う答えを見つけました。
ここにもヒントを追加します。
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());
}
デフォルト(少なくとも私が目にしているもの)がどこから来るのかという疑問があります。それらは.NETのデフォルトですか、それとも他の場所(私のプロジェクトの他の誰か)によって作成されたのでしょうか。とにかく、これが役に立てば幸いです。
これはjayson.centenoと他の回答に似たソリューションですが、の組み込み拡張機能を使用してい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
}
このソリューションは、主にWebApiの初期リリースでODataの$ formatをサポートすることを目的としていますが、非OData実装にも適用され、
Content-Type: application/json; charset=utf-8
れ、応答でヘッダー。
ブラウザーでテストするときに、URIの末尾&$format=json
または&$format=xml
末尾に追加できます。独自のヘッダーを設定できるブラウザ以外のクライアントを使用する場合、他の予想される動作を妨げることはありません。
以下のように使用できます:
GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
これらの2行のコードをWebApiConfigクラスに 追加するだけです
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
//add this two line
config.Formatters.Clear();
config.Formatters.Add(new JsonMediaTypeFormatter());
............................
}
}
次の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}"
);
}
MSDN からASP.NETとAngularJSを使用した単一ページアプリケーションの構築(約41分)。
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();
}
それは最新のはずです、私はそれを試してみました、そしてそれは働きました。
この質問が出されて(回答されて)しばらく時間が経過しましたが、別のオプションは、以下のようにMessageHandlerを使用して要求処理中にサーバーのAcceptヘッダーをオーバーライドすることです。
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);
}
}
どこ someOtherCondition
ブラウザの種類など、でもません。これは、デフォルトのコンテンツネゴシエーションをオーバーライドしたい場合がある、条件付きの場合です。それ以外の場合は、他の回答と同様に、構成から不要なフォーマッタを削除するだけです。
もちろん、登録する必要があります。これはグローバルに行うことができます:
public static void Register(HttpConfiguration config) {
config.MessageHandlers.Add(new ForceableContentTypeDelegationHandler());
}
またはルートごとに:
config.Routes.MapHttpRoute(
name: "SpecialContentRoute",
routeTemplate: "api/someUrlThatNeedsSpecialTreatment/{id}",
defaults: new { controller = "SpecialTreatment" id = RouteParameter.Optional },
constraints: null,
handler: new ForceableContentTypeDelegationHandler()
);
また、これはメッセージハンドラーであるため、パイプラインの要求側と応答側の両方でのように実行されHttpModule
ます。したがって、カスタムヘッダーを使用してオーバーライドを簡単に確認できます。
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;
}
}
これが私が自分のアプリケーションで使用した最も簡単な方法です。以下の3行のコードApp_Start\\WebApiConfig.cs
をRegister
関数に追加します
var formatters = GlobalConfiguration.Configuration.Formatters;
formatters.Remove(formatters.XmlFormatter);
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Asp.net Web APIは、返されたオブジェクトを自動的にJSONにシリアル化application/json
し、ヘッダーに追加されると、ブラウザーまたはレシーバーがJSONの結果を返していることを認識します。
Felipe Leusinの回答を何年も使用して、コアライブラリとJson.Netの最近の更新後、System.MissingMethodException
:SupportedMediaTypes に遭遇しました。私の場合の解決策は、同じ予期しない例外が発生している他の人に役立つと思いますが、インストールすることSystem.Net.Http
です。NuGetは明らかにそれをいくつかの状況で削除します。手動インストールの後、問題は解決されました。
一度インストールする必要があり、任意の API(自社またはサードパーティ)およびすべてに使用できる適切なツールを使用する代わりに、1つの API で単一のユースケース(GET)を変更するためにコーディングを必要とする非常に多くの返信に驚いていますユースケース。
だから良い答えは: