4

ここで、jquery.ajax を ie9 で動作させようとして夢中になりました。したがって、CORS を実装する ASP Web API 2 Rest API があります。すべてのブラウザからの CORS リクエストが機能します。XDomainRequest を使用するため、IE9 は機能しませんでした。IE9用のajaxTransportのカスタム実装を作成することで、うまく機能させることができました。

現在、GET リクエストは正常に機能しているようです。しかし、IE9 からポスト リクエストを実行すると、HTTP エラー 415 - サポートされていないメディア タイプが発生します。

content-type を「application/json」に設定し、「application/x-www-form-urlencoded」も試しましたが、XDomainRequest はカスタム ヘッダーを使用してすべてをサポートしていないことを理解しましたか? WebAPIで何か特定の設定が必要かどうか、またはリクエストを微調整する必要があるかどうか、誰かが知っていますか?

私のリクエストは次のようになります。

                        $.ajax({
                        url: hostname + "/api/DDC/Book",
                        type: "POST",

                        contentType: "application/json",
                        data: {
                            DealID: function () {
                                return viewModel.get("DealID");
                            },
                            LocationID: function () {
                                return viewModel.get("LocationID");
                            },
                            Time: function () {
                                return viewModel.get("selectedDateTime.Time");
                            }

                        }
                    })

サーバーにはこれがあります:

[HttpPost("DDC/Book")]
    [EnableCors(origins: "*", headers: "*", methods: "POST, GET, OPTIONS, PUT, DELETE")]
    public dynamic Post(BookModel model)
    {
       .........

IE デバッガーで失敗した要求を分析すると、これは送信される要求ヘッダーです。

Key Value
Request POST //api/DDC/Book HTTP/1.1
Accept  */*
Origin  http://myurl.com
Accept-Language hr-HR
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host    www.somehost.com
Content-Length  55
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache

私は本当にここですべての希望を失っています.

EDIT:より多くの研究から、WebAPIが機能するにはコンテンツタイプが必要であり、XDomainRequestが送信しないことがわかりました。したがって、私が見る唯一の解決策は、何も設定されていないときにデフォルトのコンテンツタイプを持つようにwebapiを微調整することです。方法はまだわかりませんが、

EDIT2: すべての POST を GET に変換することで一時的にハッキングしましたが、これがどれほどスマートかはわかりませんが、今のところ大きな問題は見られないので、問題を修正するまでは問題ありません

4

3 に答える 3

8

なんとか自分で解決しました。レイ ニコラスが指摘したように、コンテンツ タイプがない場合、ASP Web API のデフォルトは「アプリケーション/オクテット ストリーム」コンテンツ タイプです。「application/x-www-form-urlencoded」のデフォルトが必要です。

着信リクエストの「Content-Type」をチェックする独自の単純なメッセージ ハンドラーを作成することで、これを達成できました。何も存在しない場合は、「application/x-www-form-urlencoded」を追加します。

これはコードです:

public class DefaultContentTypeMessageHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Content.Headers.ContentType == null)
            request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");


        var response = await base.SendAsync(request, cancellationToken);


        return response;
    }

}

アップデート:

以下のコメントで Robert Christ が書いたように、メッセージ ハンドラを使用したことがない人のために、回答を少し拡張します。

一見わからない人のために説明すると、DelegatingHandlers を使用すると、実際に WebAPI フレームワークの内部に到達する前に、リクエスト/レスポンス オブジェクトを変更できます。カスタム モデル バインダーを実際に作成せずに、モデル バインドの前に着信要求を実際に変更できるフレームワークは他にありません (笑)。代わりに、null コンテンツ タイプ (XDomainRequest 仕様の欠点によって保証されています) を見つけ出し、それを xml または json に更新すると、着信要求を正しく解析できるようになります。

メッセージ ハンドラーを作成したら、それを WebAPI に登録する必要があります。これは WebApiConfig クラスで行います。

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {

        config.MessageHandlers.Add(new DefaultContentTypeMessageHandler());
        // Rest of your code

     }
 }
于 2013-09-24T16:03:10.883 に答える
1

上記の Dennis の回答では、.NET 4.5 でのみ使用できる async を使用しています。.NET 4 以下の可能性がある場合は、代わりに次の委任ハンドラーを使用します。

 public class DefaultContentTypeMessageHandler : DelegatingHandler
 {
      protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
      {
          if (request.Method == HttpMethod.Post && request.Content.Headers.ContentType == null)
          {
              request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
          }
          return base.SendAsync(request, cancellationToken);
      }
 }

また、USING ステートメントを忘れないでください。次のものが必要になります。

using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
于 2013-10-03T09:44:07.467 に答える