32

私は ASP.NET WebAPI RC を使用しており、何も凝っていない API コントローラーをホストしています。JSON ではすべて正常に動作しますが、Accepts ヘッダーを使用してさまざまな形式のリクエストをテストしていますが、ここで問題が発生しています。

jQuery を使用して AJAX リクエストを発行し、リクエストの「dataType」パラメーターを設定しています。これにより、以下に示すように、適切な Accept ヘッダーが正しく設定されます。

$.ajax({
    type: method,
    url: url,
    dataType: "xml",
    data: data || null,
    success: function (data) {
        // omitted
    }
});

これは、フィドラーのリクエスト/レスポンスの保存です。ご覧のとおり、Accept ヘッダーには application/xml と示されていますが、WebAPI は JSON を返しました。Acceptヘッダーを「application/xml」だけに手動で設定しようとしました(したがって、text/htmlも含まれていません)が、役に立ちませんでした。

私は一体何が欠けているのですか?(注:データ内の機密情報をいくつか切り取りましたが、それ以外は微調整していません)

GET http://localhost/insp**snip**6716 HTTP/1.1
Host: localhost
Connection: keep-alive
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.1 (KHTML, like Gecko) Chrome/21.0.1180.60 Safari/537.1
Accept: application/xml, text/xml, */*; q=0.01
Referer: http://localhost/inspector/api/test?
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: m=34e2:|2c69:t|47ba:t|4e99:t; .INSPECTOR3COOKIE=08BA683091E2A457B1832E9B*snip*F911D9ED97076


HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
Persistent-Auth: true
X-Powered-By: ASP.NET
Date: Fri, 03 Aug 2012 22:27:42 GMT
Content-Length: 1816

{"Id":2416716,"ProjectId":36,"Url":"http://ins *snip, but obviously this is JSON not XML *

AppStart などのフォーマッターを微調整していないことを指摘しておきたいと思います。そのため、私が理解している限り、JSON および XML フォーマッターはデフォルトで有効にする必要があります。

更新:私はそれを理解しました-以下の私自身の答えをチェックしてください

4

7 に答える 7

42

私はそれを考え出した!

DataContract シリアライザーではなく Xml シリアライザーが必要だったので、AppStart でこれを使用しました。

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;

しかし...どうやら私のモデルには、Xmlシリアライザーにシリアル化できないと思わせる何かがあります。私は、WebAPI が代わりに JSON フォーマッタを使用することを決定する原因になっていると推測しています。

この無害に見える設定が実際に使用されるフォーマッターに影響を与える可能性があることは、まったく直感的ではありません。WebAPIの人々がこれを見ることを願っています:)

このような問題をデバッグできるように、コンテンツ ネゴシエーション プロセスの入力と出力を理解できる何らかのツールがあれば便利です。

于 2012-08-03T23:00:49.080 に答える
14

同じ問題がありましたが、返していたすべてのモデルにデフォルトのコンストラクターを追加することで修正しました。

XML シリアライザーは空のモデル オブジェクトを作成し、プロパティのセッターを介してデータを設定します。セッターが保護されているかプライベートである場合、そのプロパティもシリアライズされません

于 2013-07-17T14:06:32.503 に答える
12

このスレッドの現在の回答では、すでに多くの理由が指摘されていますが、要約すると、XmlSerializer は限られた数の型しかサポートしていません。

「最適な」フォーマッタを探す場合、AASoft で正しく説明されているように、DefaultContentNegotiator は各フォーマッタに特定のタイプをサポートできるかどうかを尋ねます。次に、これらのフォーマッタをリクエストの Accept ヘッダーと照合します。

受け入れヘッダーに基づいて一致が見つからない場合は、タイプをシリアル化できる最初のもの (この場合は JSON フォーマッター) を選択します。ただし、DefaultContentNegotiator を構成して、既定の形式を返す代わりに、406 None Accepted ステータス コードを返すことができます。これは、一致する表現が見つからなかったことをクライアントに示し、クライアントが使用できない可能性があるデータを送信する代わりに、エラー応答を生成します。

このオプションの設定については、ブログ「ASP.NET Web API の更新 – 5 月 14 日」[1] の「コンテンツ ネゴシエーションの改善」セクションで説明されています。

お役に立てれば、

ヘンリク

[1] http://blogs.msdn.com/b/henrikn/archive/2012/05/14/asp-net-web-api-updates-may-14.aspx

于 2012-08-04T05:14:57.617 に答える