ASP.NETMVCコントローラーアクションに対してクロスドメインPOST要求を実行しようとしています。このコントローラーアクションは、さまざまなパラメーターを受け入れて使用します。問題は、プリフライトリクエストが発生すると、コントローラーアクションが実際に実行を試み、OPTIONSリクエストがデータを渡さないため、コントローラーアクションが500HTTPエラーをスローすることです。パラメータを使用するコードまたはパラメータ自体を削除すると、リクエストチェーン全体が正常に完了します。
これがどのように実装されるかの例:
コントローラのアクション
public ActionResult GetData(string data)
{
return new JsonResult
{
Data = data.ToUpper(),
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
クライアント側のコード
<script type="text/javascript">
$(function () {
$("#button-request").click(function () {
var ajaxConfig = {
dataType: "json",
url: "http://localhost:8100/host/getdata",
contentType: 'application/json',
data: JSON.stringify({ data: "A string of data" }),
type: "POST",
success: function (result) {
alert(result);
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Error: Status: ' + textStatus + ', Message: ' + errorThrown);
}
};
$.ajax(ajaxConfig);
});
});
</script>
これで、プリフライトリクエストが発生するたびに、500 HTTPコードが返されます。これは、「data」パラメータがnullであるため、OPTIONSリクエストが値を渡さないためです。
サーバーアプリケーションは、ローカルIISのポート8100にセットアップされており、クライアント側のコードを実行するページは、クロスドメイン呼び出しを模倣するようにポート8200にセットアップされています。
また、次のヘッダーを使用してホスト(8100上)を構成しました。
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Origin: http://localhost:8200
私が見つけた回避策の1つは、アクションを実行するHTTPメソッドをチェックし、それがOPTIONSリクエストの場合は空白のコンテンツを返すだけで、それ以外の場合はアクションコードを実行することでした。そのようです:
public ActionResult GetData(string data)
{
if (Request.HttpMethod == "OPTIONS") {
return new ContentResult();
} else {
return new JsonResult
{
Data = data.ToUpper(),
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
しかし、このアプローチは私には非常に不格好に感じます。この種のロジックをに追加することを検討しましたAttribute
が、これでも、CORSを使用して呼び出されるすべてのアクションを装飾することを意味します。
この機能を機能させるためのより洗練されたソリューションはありますか?