web-dev-qa-db-ja.com

Chromeを使用してASP.NET Web APIからXMLではなくJSONを返す方法を教えてください。

新しい ASP.NET Web APIを使用する Chrome XMLを見ている - request _ json _ に変更するにはどうすればよいですか。ブラウザ?私はそれがリクエストヘッダの一部に過ぎないと信じています、それで正しいですか?

1220
naspinski

MVC Web APIプロジェクトのApp_Start / WebApiConfig.csクラスに次のコードを追加しただけです。

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

これでほとんどのクエリで確実にjsonを取得できますが、text/xmlを送信するとxmlを取得できます。

あなたがContent-Typeとしての応答application/jsonを持つ必要があるならば、 以下をチェックしてください - Toddの答え

NameSpaceSystem.Net.Http.Headersを使用しています。

1643
Felipe Leusin

WebApiConfigでこれを行うと、デフォルトでJSONが得られますが、request Acceptヘッダーとしてtext/xmlを渡すと、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プロジェクトタイプを使用していないため、最初にこのクラスがなかった場合は、 この回答を参照してください を組み込む方法の詳細については/ /を参照してください。

486
Glenn Slaven

私は好きです 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());
294
Todd Menier

RequestHeaderMappingを使用すると、レスポンスヘッダーにContent-Type = application/jsonも設定されるため、Firefoxの(JSONViewアドオンを使用)レスポンスをJSONとしてフォーマットできるため、RequestHeaderMappingの使用がさらに効果的です。

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

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

WebApiConfig.cs で、 Register 関数の最後に追加します。

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

ソース

106

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

WebAPIのコンテンツネゴシエーションを見てください。これらの( 第1部第2部 )は素晴らしく詳細で徹底的なブログ記事がそれがどのように働くかを説明します。

要するに、あなたは正しい、そして単にAcceptContent-Typeリクエストヘッダを設定する必要があります。あなたのActionが特定のフォーマットを返すようにコード化されていないのであれば、Accept: application/jsonを設定することができます。

51
Aaron Daniels

質問はChrome固有のものであるため、リクエストのコンテンツタイプを設定できる Postman拡張子 を取得できます。

Postman

40
Chris S

手っ取り早い方法の1つは、MediaTypeMapping特殊化を使用することです。以下は、Application_StartイベントでQueryStringMappingを使用する例です。

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

この場合、URLにクエリ文字列?a = bが含まれるたびに、Jsonの応答がブラウザに表示されます。

32
suhair

このコードは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"));

みんな、ありがとう!

28
jayson.centeno

APIをテストするためにブラウザを使用しないでください。

代わりに、CURLやFiddlerなど、リクエストを指定できるHTTPクライアントを使用してください。

この問題の問題は、APIではなくクライアントにあります。 Web APIは、ブラウザの要求に従って正しく動作します。

18
dmyoko

上記の答えのほとんどは完全に理にかなっています。データが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がデフォルトのフォーマットなので

13
pavan kumar

Accept: application/xmlヘッダーに "Chrome"が含まれている場合は、グローバルアクションフィルターを使用して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();
    }
}

動作しているようです。

8
Roger Lipscombe

私はChromeアプリ "Advanced REST Client"がRESTサービスと連携するのに優れていることを見つけました。 Content-Typeをapplication/jsonに設定することができます。 Advanced REST client

7
Mike Rowley

正しい形式を返すことは、メディアタイプフォーマッタによって行われます。他の人が言ったように、あなたは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
}

アクションの装飾でWordのAttributeを省略して、[JsonOutput]の代わりに[JsonOutputAttribute]だけを使用できることに注意してください。

5
Stacked

答えにこのような複雑さのすべてがあるのはなぜかは私には分かりません。 QueryStrings、ヘッダー、およびオプションを使って、これを実行できる方法はたくさんあります。ただし、ベストプラクティスと考えるのは簡単です。プレーンなURL(例:http://yourstartup.com/api/cars)をリクエストすると、JSONが返されます。適切なレスポンスヘッダを付けてJSONを取得します。

Content-Type: application/json

これとまったく同じ質問に対する答えを探していると、私はこのスレッドを見つけました。そして、この受け入れられた答えは正確には機能しないので、続けなければなりませんでした。私は答えを見つけましたが、それは単純すぎて最高の答えではないと感じました。

デフォルトのWebAPIフォーマッタを設定します

ここに私のヒントを追加します。

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のデフォルトですか、それとも他の場所で(私のプロジェクトの他の誰かによって)作成されたのでしょうか。さて、これが役立つことを願っています。

4
Nick
        config.Formatters.Remove(config.Formatters.XmlFormatter);
3
Gaurav Dubey

aSP.net WebApi 2の最新バージョンによれば、

WebApiConfig.csの下では、これはうまくいくでしょう

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

これは 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の$フォーマットをサポートすることを主な目的としていましたが、OData以外の実装にも適用され、応答にContent-Type: application/json; charset=utf-8ヘッダーを返します。

ブラウザでテストするときに、&$format=jsonまたは&$format=xmlをあなたのURIの最後まで付けることができます。独自のヘッダを設定できるブラウザ以外のクライアントを使用している場合は、他の予想される動作を妨げることはありません。

3
mdisibio

あなたは以下のように使うことができます:

GlobalConfiguration.Configuration.Formatters.Clear();
GlobalConfiguration.Configuration.Formatters.Add(new JsonMediaTypeFormatter());
2
Akshay Kapoor

WebApiConfig クラスにこれらの2行のコードを追加するだけです。

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


          ............................
      }
}
2

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

_ msdn _ ASP.NETとAngular JSを使用した単一ページアプリケーションの構築 (約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();
    }

それは最新であるべきです、私はそれを試みました、そして、それは働きました。

1
lko

この質問が行われてから回答が得られてからしばらく時間が経っていますが、次のように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;
    }
}
1
rism

これが私のアプリケーションで使用した最も簡単な方法です。以下の3行のコードをRegister関数のApp_Start\\WebApiConfig.csに追加

    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結果を返すことを認識します。

1
Vikas Bansal

Felipe Leusin の答えを使って何年もの間、最近コアライブラリとJson.Netを更新した後、私はSystem.MissingMethodException:SupportedMediaTypesに出会いました。私の場合の解決策は、同じ予想外の例外を経験している他の人たちに役立つと思いますが、System.Net.Httpをインストールすることです。 NuGetは明らかに状況によってはそれを削除します。手動インストールの後、問題は解決しました。

0
Charles Burns

WebApiConfigは、jsonとxmlのどちらで出力するかを設定できる場所です。デフォルトではxmlです。 register関数では、HttpConfiguration Formatterを使って出力をフォーマットできます。 System.Net.Http.Headers => MediaTypeHeaderValue( "text/html")は、json形式で出力を取得するために必要です。 enter image description here

0
Parag