2014-01-17 3 views
11

C#のHttpClient PostAsyncターンに204本WEBAPIサービスを考えると404

[ActionName("KillPerson")] 
[HttpPost] 
public void KillPerson([FromBody] long id) 
{ 
    // Kill 
} 

そしてこのHttpClientをPostAsyncコール:

var httpClient = new HttpClient { BaseAddress = new Uri(ClientConfiguration.ApiUrl) }; 
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); 
var serializerSettings = new JsonSerializerSettings 
{ 
    PreserveReferencesHandling = PreserveReferencesHandling.Objects, 
    Formatting = Formatting.Indented, 
    ReferenceLoopHandling = ReferenceLoopHandling.Serialize 
}; 
var serializedParameter = JsonConvert.SerializeObject(parameter, serializerSettings); 
var httpContent = new StringContent(serializedParameter, Encoding.UTF8, "application/json"); 
var response = await httpClient.PostAsync(serviceUrl, httpContent).ConfigureAwait(false); 
response.EnsureSuccessStatusCode(); 

私は)(response.EnsureSuccessStatusCodeを期待します。その代わりに404をスローします。 面白いことに、フィドラーは、webapiサービスが期待通りに204を返していることをmedに伝え、私がそれをデバッグするとき、KillPersonは問題なく動作します。

更新: クライアントコードがPCLまたはSilverlight 5プロジェクト内にある場合にのみこれが発生することが判明しました。私がWindowsフォームアプリケーションでそれを複製すると、まったく同じコードが204になります。 PCLに含まれているクライアントコードにWindows Formsアプリケーションをポイントすると、私には404が返されます。

アップデート2: (それは私がそれを実行する必要があるのは終わりに私を気にしないが)これで問題が解決:

[ActionName("KillPerson")] 
[HttpPost] 
public HttpResponseMessage KillPerson([FromBody] long id) 
{ 
    return this.Request.CreateResponse(HttpStatusCode.OK); 
} 

これは、404(シオマネキはまだ204と非Silverlightのクライアントが正常に動作言い再導入)

[ActionName("KillPerson")] 
[HttpPost] 
public HttpResponseMessage KillPerson([FromBody] long id) 
{ 
    return this.Request.CreateResponse(HttpStatusCode.NoContent); 
} 

アップデート3(解決): は、最後にこれを考え出しました。 SilverlightでブラウザまたはクライアントのHTTP処理のいずれかを選択できるようです。ブラウザのHTTP処理を使用すると、さまざまなレスポンスコードやヘッダーを含む多くのものがサポートされません。 のHttpClientはそれを修正呼び出す前に、これらの行を追加:

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); 
WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); 
+0

サービスのエンコーディングはクライアントと一致していますか?クライアントの404は、応答を膨らませているときに、期待していたものと一致しないことを私に示唆しています。 –

+0

はい - これはvoid(204)メソッドでのみ発生します。文字列を返すようにKillPersonサービスを変更すると正常に動作します。 – user2083690

+0

あなたのアップデートを考えると、これは特に有用ではありませんが、私はコンソールアプリケーションで正しい機能を持っています:(204を返す)https://gist.github.com/brainwipe/8472430 AppDomain設定があると思いますどこかでグローバルに設定されたエンコーディングです。 –

答えて

4

最後にこれを考え出しました。 SilverlightでブラウザまたはクライアントのHTTP処理のいずれかを選択できるようです。ブラウザのHTTP処理を使用すると、さまざまなレスポンスコードやヘッダーを含む多くのものがサポートされません。 HttpClientを呼び出す前にこれらの行を追加してください:

WebRequest.RegisterPrefix("http://", WebRequestCreator.ClientHttp); 
WebRequest.RegisterPrefix("https://", WebRequestCreator.ClientHttp); 
1

の方法にHttpResponseMessage戻り値のを追加すると、これを行うための文書化の方法ですので、あなたが見つけた解決策は本当に最高です。

しかし、あなたがそのようにすべてのあなたの空のメソッドを変更したくない場合は、代替はオンザフライでレスポンスコードを変更するには、委任ハンドラを追加することができ - このような何か:

public class ResponseHandler : DelegatingHandler 
{ 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     var response = base.SendAsync(request, cancellationToken); 

     if (request.Method == HttpMethod.Post) 
     { 
      response.Result.StatusCode = response.Result.IsSuccessStatusCode ? System.Net.HttpStatusCode.OK : response.Result.StatusCode; 
     } 
     return response; 
    } 
} 

注:のステータスコードがすべて(成功した場合)のステータスコードに変更されます。特定のルート/メソッドに対してのみ、コードを追加する必要がある場合は、コードを追加する必要があります(異なるポストメソッドを別々に扱う必要がある場合)。

関連する問題