2014-01-17 1 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을 기대; succede하지만 대신 404를 던집니다. 재미있는 점은 피들러가 medapi에게 WebAPI 서비스가 예상대로 204를 반환한다고 말하면서 디버깅 할 때 KillPerson이 문제없이 실행된다는 것입니다.

업데이트 : 클라이언트 코드가 PCL 또는 Silverlight 5 프로젝트 내에있는 경우에만 발생하는 것으로 확인되었습니다. Windows Forms 응용 프로그램에서 똑같은 코드를 복제하면 예상되는 204 번 코드가 제공됩니다. PCL에 포함 된 클라이언트 코드로 Windows Forms 응용 프로그램을 가리키면 다시 404를 제공합니다.

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

이것은 404 (피들러는 여전히 (204) 및 비 실버 클라이언트가 잘 실행 말한다 재 도입 :

갱신 2 : (그것은 내가 그것을해야한다 끝 날 귀찮게하지하지만) 이이 문제를 해결합니다)

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

업데이트 3() 해결 : 마지막이 알아 냈어. Silverlight에서 브라우저 또는 클라이언트 HTTP 처리 중 하나를 선택하는 것으로 보입니다. 브라우저 HTTP 처리를 사용할 때 다양한 응답 코드와 헤더를 포함하여 많은 내용이 지원되지 않습니다.

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의 returntype의입니다 추가, 그래서 당신이 발견 한이 솔루션은 정말 최고입니다 : 추가이 줄 HttpClient를 호출하기 전에 고정.

그러나 당신이 그런 식으로 모든 무효 방법을 변경하지 않는 경우, 대안은 즉시 응답 코드를 변경하기 위해 위임 처리기를 추가 할 수 - 이런 식으로 뭔가 :

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; 
    } 
} 

참고 :에 대한 상태 코드가 모두 (성공한 경우)으로 변경됩니다. 특정 라우트/메소드에 대해서만 수행되도록하려면 코드를 추가해야합니다 (다른 포스트 메소드가 다르게 처리되어야하는 경우).