ASP.NET WebApiのPost処理(C#)を、Windowsフォームアプリ(C#)から、HttpClient の PostAsyncメソッドを使って呼ぼうとしているのですが、どうもうまくいきません。
###発生している問題・エラーメッセージ
以下が返されて、対象のPostメソッドは呼ばれません。
The requested resource does not support http method 'GET'.
###ソースコード
まず、WebApiの記述です。
C#
1 [RoutePrefix("api/GateApi")] 2 public class GateApiController : ApiController 3 { 4 // パラメータ用のクラス定義 5 public class para 6 { 7 public int GateNo { get; set; } 8 } 9 10 // Post処理 11 [Route("TestPost")] 12 [HttpPost] 13 public string TestPost(para data) 14 { 15 return "Post呼ばれたよ"; 16 } 17 } 18
試しに、同じサイト内のページに埋め込んだ、以下のJavascriptでPOSTしてみましたが、これは正常に処理されます。
値も正常に渡るし、戻り値も返っています。
JavaScript
1 function testPost() { 2 $.ajax( 3 "/api/GateApi/TestPost/", 4 { 5 type: "POST", 6 data: { GateNo: 333 }, 7 success: function (data) { 8 alert(data); 9 }, 10 error: function (e) { 11 alert("エラー"); 12 } 13 }); 14 }
以下が、Windows Formのソースの一部です。
ボタンをクリックするとレスポンスがラベルに表示されます。
C#
1 private void button_Click(object sender, EventArgs e) 2 { 3 PostWebPageAsync(); 4 } 5 6 private async void PostWebPageAsync() 7 { 8 this.label1.Text = "Post取得中"; 9 10 string uri = "http://localhost:12345/api/GateApi/TestPost/"; 11 12 // "Message":"The requested resource does not support http method 'GET'. が返されます。 13 this.label1.Text = await Post(uri, 14 new Dictionary<string, string> {{ "GateNo", "123" }}); 15 } 16 17 // Post呼び出し処理 18 private async Task<string> Post(string url, Dictionary<string, string> param) 19 { 20 string result = ""; 21 22 try 23 { 24 HttpClient httpClient = new HttpClient(); 25 httpClient.MaxResponseContentBufferSize = int.MaxValue; 26 HttpContent content = new FormUrlEncodedContent(param); 27 var response = await httpClient.PostAsync(url, content); 28 String text = await response.Content.ReadAsStringAsync(); 29 30 result = text; 31 } 32 catch (Exception Err) 33 { 34 result = "ERROR: " + Err.Message; 35 } 36 37 return result; 38 }
例外は発生していないようですが、ラベルには、
** "Message":"The requested resource does not support http method 'GET'. **
が表示されます。
response.StatusCode は MethodNotAllowed が返されます。
何か、ヘッダなど必要な情報があるんでしょうが、よくわかりません。
###補足情報
サーバー側もクライアント側も、.NETのバージョンは 4.5.1
IISのログの抜粋です
■うまくいくとき → ChromeのRest Client で呼び出し
2015-10-13 03:06:50 ::1 POST /api/GateApi/TestPost - 12345 - ::1 Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/45.0.2454.101+Safari/537.36 - 200 0 0 2620
■うまくいかないとき → WindowsForm で呼び出し
2015-10-13 03:09:21 ::1 POST /api/GateApi/TestPost/ - 12345 - ::1 - - 302 0 0 13
2015-10-13 03:09:21 ::1 GET /api/GateApi/TestPost/ AspxAutoDetectCookieSupport=1 53903 - ::1 - - 405 0 0 266
上記ログ(うまくいかないほう)とソースの対応を調べたのですが、
1行目: var response = await httpClient.PostAsync(url, content); → POST
2行目: String text = await response.Content.ReadAsStringAsync(); → GET
ということでした。
1行目の処理で、エラーが帰りそのため2行目のGETがうまくいかないということのようです。
1行目POST時の戻り値の内容を一部抜粋
IsSuccessStatusCode: false ReasonPhrase: "Method Not Allowed" RequestMessage: {Method: POST, RequestUri: 'http://localhost:12345/api/GateApi/TestPost/?AspxAutoDetectCookieSupport=1', Version: 1.1, Content: System.Net.Http.FormUrlEncodedContent, Headers:
{
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
}}
###[その後の調査]
eripong さん
貴重な情報ありがとうございます。
セッションIDの受渡のために、クッキーを使うかどうかの設定の話だと思うんですが、私の知識では、いまいち細かいしくみがわかりません。ただ、これを機に多少とも勉強させていただきます。
最低限の私の知識で理解できる範囲で、以下いろいろやってみました。
■まず、cookieless の設定による実行結果です。(○がPOST成功)
× UseUri
○ UseCookies
× AutoDetect
○ UseDeviceProfile
おっしゃるように、UseCookiesだとうまくいくようで、UseDeviceProfileでも大丈夫みたいです。
つまり、設定としては、
-
<sessionState mode="Off" />
-
<sessionState cookieless="UseCookies"/>
-
<sessionState cookieless="UseDeviceProfile"/>
のいずれかだとうまくいくということになります。
■次に、Chromeのクッキーの状態を見てみました。
AspxAutoDetectCookieSupportの値が1として保存されているようです。
試しに、これを削除して、JavascriptやREST ClientツールでGETしてみると、見事にエラーになります。
ただ、このときに再度AspxAutoDetectCookieSupport=1 が保存され、2回目以降はエラーにならないようです。
■REST Client でのPOST実行結果
各処理のリクエストの内容を細かく調べる方法がわからないので、とりあえず情報として載せておきます。
以下は、REST Client でPOSTに失敗した時の状況です。
POST時に、AspxAutoDetectCookieSupport=1にリダイレクトしてるということでしょうか。その結果「405 Method Not Allowed」が返されています。そして、その後、GETしようとしてエラー返されているようです。
回答2件
あなたの回答
tips
プレビュー