program tip

WebApi 컨트롤러에서 HttpContent 읽기

radiobox 2020. 11. 14. 10:05
반응형

WebApi 컨트롤러에서 HttpContent 읽기


MVC webApi 컨트롤러 작업에서 PUT 요청의 내용을 어떻게 읽을 수 있습니까?

[HttpPut]
public HttpResponseMessage Put(int accountId, Contact contact)
{
    var httpContent = Request.Content;
    var asyncContent = httpContent.ReadAsStringAsync().Result;
...

여기에 빈 문자열이 있습니다.

내가해야 할 일은 : 초기 요청에서 수정 / 전송 된 "어떤 속성"을 파악하는 것입니다 (즉, Contact개체에 10 개의 속성이 있고 그중 2 개만 업데이트하려는 경우 전송 및 개체에 2 개의 속성 만있는 경우, 이 같은:

{

    "FirstName": null,
    "LastName": null,
    "id": 21
}

예상되는 최종 결과는 다음과 같습니다.

List<string> modified_properties = {"FirstName", "LastName"}

설계 상 ASP.NET Web API의 본문 콘텐츠는 한 번만 읽을 수있는 전달 전용 스트림으로 처리됩니다.

귀하의 경우 첫 번째 읽기는 Web API가 모델을 바인딩 할 때 수행되고 그 후에는 Request.Content아무것도 반환하지 않습니다.

contact작업 매개 변수에서 를 제거하고 콘텐츠를 가져 와서 수동으로 객체로 역 직렬화 할 수 있습니다 (예 : Json.NET 사용).

[HttpPut]
public HttpResponseMessage Put(int accountId)
{
    HttpContent requestContent = Request.Content;
    string jsonContent = requestContent.ReadAsStringAsync().Result;
    CONTACT contact = JsonConvert.DeserializeObject<CONTACT>(jsonContent);
    ...
}

그것은 트릭을 수행해야합니다 ( accountIdURL 매개 변수이므로 콘텐츠 읽기로 처리되지 않는다고 가정 ).


다음 접근 방식으로 CONTACT 매개 변수를 유지할 수 있습니다.

using (var stream = new MemoryStream())
{
    var context = (HttpContextBase)Request.Properties["MS_HttpContext"];
    context.Request.InputStream.Seek(0, SeekOrigin.Begin);
    context.Request.InputStream.CopyTo(stream);
    string requestBody = Encoding.UTF8.GetString(stream.ToArray());
}

내 매개 변수 개체의 json 표현이 반환되었으므로 예외 처리 및 로깅에 사용할 수 있습니다.

여기에 허용 된 답변으로 확인 됨


이 솔루션이 분명해 보일 수 있지만 여기에 게시하여 다음 사람이 더 빨리 검색 할 수 있도록했습니다.

메서드에서 모델을 매개 변수로 계속 유지하려면을 생성 DelegatingHandler하여 콘텐츠를 버퍼링 할 수 있습니다 .

internal sealed class BufferizingHandler : DelegatingHandler
{
    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        await request.Content.LoadIntoBufferAsync();
        var result = await base.SendAsync(request, cancellationToken);
        return result;
    }
}

글로벌 메시지 핸들러에 추가합니다.

configuration.MessageHandlers.Add(new BufferizingHandler());

이 솔루션은 Darrel Miller답변기반으로합니다 .

이렇게하면 모든 요청이 버퍼링됩니다.


The easiest way to read the content of any request usually is to use an http proxy like fiddler

That has the massive advantage of showing you all local traffic (plus the complete requests - headers etc) and lots of other requests which reading the Request content inside a particular action in a particular controller will not show you - e.g. 401 / 404 etc.

You can also use fiddler's composer to create test requests from scratch or by modifying previous requests.

If you for some reason cannot use a proxy or must view the request from inside the web app then this answer looks sensible

참고URL : https://stackoverflow.com/questions/12494067/read-httpcontent-in-webapi-controller

반응형