GET, POST 및 PUT간에 균등하게 분할 된 수십 개의 RESTful 메서드가있는 웹 API 프로젝트가 있습니다. 이 시스템은 Nuget의 Entity Framework 객체와 Newtonsoft의 JSON (버전 9.0.1)을 사용합니다.POST 및 PUT ReadAsAsync()가 null이지만 ReadAsStringAsync()가 채워진 이유는 무엇입니까? 일명 "청킹을 해제하려면 어떻게합니까?"
내가 최근에 한 일은 갑자기 모든 POST와 PUT을 손상 시켰습니다. 나는 POST/PUTting 인 [FromBody] 객체가 null로 도착한다는 것을 알게되었습니다.
그래서 내 "사용자 업데이트"방법은 ...과 같이
[HttpPut]
public IHttpActionResult Put([FromBody] User user)
보이는 ...하지만 "사용자는"항상 null 도착한다. 마찬가지로 이렇게하면 ...
var obj = Request.Content.ReadAsAsync<object>().Result;
... 그러면 obj가 null입니다. 나는이 작업을 수행 할 경우
는하지만 ...
var jsonString = Request.Content.ReadAsStringAsync().Result;
는 ... 그때는 예상 JSON을 얻을. (그러나 내 아키텍처에서는 JSON을 원하지 않는다. 객체를 원한다.)
은 이미 요청을 읽었을 때 이해할 수있는 것으로 예상된다. 함유량. 내용 스트림은 되감기 가능하지 않으며 마지막 바이트로 설정됩니다. .ReadAsStringAsync() 및 .ReadAsByteArrayAsync()는 스트림을 복사하고 처리하는 것으로 가정합니다.
나는 이것을 HttpClient를 사용하는 WPF 응용 프로그램에서 호출합니다. 샘플 호출 ...
using (HttpClient http = API.GetHttpClient())
{
string url = string.Format("{0}/User", thisApp.WebAPI_BaseUrl);
RILogManager.Default.SendString("url", url);
JsonMediaTypeFormatter formatter = new JsonMediaTypeFormatter() ;
formatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
HttpResponseMessage response;
response = http.PutAsync<User>(url, user, formatter, "application/json").Result;
...
내 "API.GetHttpClient()"루틴은 다음과 같습니다. DelegateHandler를 사용하여 클라이언트 쪽에서 JWT 작업을하고있는 것을 볼 수 있습니다. 그러나 여기서는 적절하지 않다고 생각합니다. 그것은 들어오는 응답, 나가는 요청을 만지지 않습니다.
public static HttpClient GetHttpClient(bool WithAuthToken = true)
{
App thisApp = (App)System.Windows.Application.Current;
//HttpClient http = new HttpClient();
HttpClient http = HttpClientFactory.Create(new JWTExpirationHandler());
http.BaseAddress = new Uri(thisApp.WebAPI_BaseUrl);
http.DefaultRequestHeaders.Accept.Clear();
http.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
if(WithAuthToken)
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", JWT);
return http;
}
들어오는 요청이 "application/json"및 UTF-8의 콘텐츠 유형임을 확인했습니다.
웹 서버에 두 개의 DelegatingHandler가 있지만 문제가없는 것 같습니다. 첫 번째 맨 위에있는 ReadAsAsync()를 끝내면 null이기도합니다. ReadAsStringAsync()는 JSON을 반환합니다.
그래서 ... 내가 뭘 잘못하고 있니? 다시 말하지만,이 작업은 훌륭했습니다. 무언가가 바뀌 었습니다. 모두 POST와 PUT이 이렇게 부러졌습니다.
내 클래스에서 [Serializable]을 제거한다고 말하는 링크를 보았습니다. 그러나 이것들은 여러 곳에서 사용하는 Entity Framework 클래스이며, 그렇게하고 싶지 않습니다.
마침내 내가 우편 게시자를 통해이 업데이트 PUT을 호출하면 작동합니다. 내 자신의 클라이언트에서 HttpRequests 비교
UPDATE
, 그리고 우체부에서, 나는 전자는 "청크"하고 후자는없는 것을 알 수있다. 이것은 중요한 단서처럼 보입니다.나는 다른 사람들이 같은 취급을 참조하십시오
내가 오프 청크 설정하는 방법의 명확한 표시를 찾을 수 없습니다. I 을 수행하십시오. 청킹을 해제하는 속성이 있음을 알지만 그렇게하면 도움이되지 않습니다.
질문 : "선택"을 청크로 트리거하는 것은 무엇입니까? 클라이언트가이 작업을 수행하기로 선택 했습니까? 아니면 컨트롤러 또는 두 작업 사이의 일부 협상입니까?
WPF 앱에서 사용하는 User 개체가 WebApi 끝점의 개체와 일치합니까? 당신은 최근에 한 일을 말해줍니다. 모델을 업데이트 했습니까? 한 가지 요점으로, 저는 EF Entity Model을 Api Controller에서 보내지 않는 것이 좋습니다. 그것을 단순한 Dto에 맵핑하고 보내십시오. 여기에 좋은 블로그가 있습니다 .http : //codethug.com/2015/02/13/web-api-deep-dive-dto-transformations-and- automapper-part-5-of-6/이것은 문제가되지 않을 수도 있지만 다루기가 더 쉽고 안전하며 – MartinM
을 다루는 데이터에 대한 명확한 그림을 제공합니다. Thanks, @MartinMilsom. User 개체는 동일합니다. .edmx 파일이 하나의 프로젝트에 있고 .tt 파일이 다른 모든 프로젝트가 참조하는 "공통"프로젝트에 있도록 솔루션을 정리했습니다. 따라서 .edmx를 변경하면 개체가 변경되지만 솔루션의 모든 프로젝트는 동일한 User/다른 개체를 공유합니다. – TomK
나는 본다. 그러나 Api를 통해 Entity를 보내면 변경으로 인해 문제가 발생할 수 있습니다. 예를 들어 json/xml serialiser가 직렬화를 해제하는 방법을 모르는 속성이 추가되거나 생성자에 일부 논리를 추가했거나 생성자를 개인용으로 만든 경우 등이 모두 예일뿐입니다. 그러나 잘못 될 수있는 제비가 있습니다. json 문자열을 수동으로 유형을 비 직렬화하려는 경우 - 오류가 있는지 확인하는 것이 좋습니다. JsonConvert.DeserializeObject (jsonString); –
MartinM