[asp.net-web-api] FromBody와 FromUri를 지정해야하는 이유는 무엇입니까?

ASP.NET 웹 API에 FromBodyFromUri속성이 필요한 이유는 무엇 입니까?

속성을 사용하는 것과 사용하지 않는 것의 차이점은 무엇입니까?



답변

ASP.NET 웹 API는 컨트롤러에서 메소드를 호출 할 때 매개 변수 바인딩 이라는 프로세스 매개 변수의 값을 설정해야합니다 .

기본적으로 Web API는 다음 규칙을 사용하여 매개 변수를 바인드합니다.

  • 매개 변수가 “단순”유형 인 경우 Web API는 URI 에서 값을 가져 오려고 시도합니다 . 간단한 형식에는 .NET 기본 형식 (int, bool, double 등)과 TimeSpan, DateTime, Guid, decimal 및 string과 문자열에서 변환 할 수있는 형식 변환기가있는 형식이 포함됩니다.

  • 복잡한 유형의 경우 Web API는 미디어 유형 포맷터를 사용하여 메시지 본문에서 값을 읽으려고합니다 .

따라서 위의 기본 동작을 무시하고 Web API가 URI에서 복합 유형을 읽도록하려면 [FromUri]속성을 매개 변수에 추가하십시오 . Web API가 요청 본문에서 단순 유형을 읽도록하려면 [FromBody]속성을 매개 변수에 추가하십시오 .

따라서 귀하의 질문에 대답하기 위해 Web API에서 [FromBody][FromUri]속성 의 필요성은 필요한 경우 위에서 설명한 기본 동작을 재정의하는 것입니다. 여기에 설명 된대로 컨트롤러 메소드에는 두 가지 속성을 사용할 수 있지만 다른 매개 변수에만 사용할 수 있습니다 .

훨씬 정보 는 “매개 변수 바인딩 웹 API를”구글 경우 웹은.


답변

기본 동작은 다음과 같습니다.

  1. 매개 변수가있는 경우 기본 유형 ( int, bool, double, …), 웹 API의 시도는의 값 얻을 URI 는 HTTP 요청을.

  2. 들어 복잡한 유형 (예를 들어 자신의 개체, : Person), 웹 API의 시도는의 값 읽어 HTTP 요청의를.

따라서 다음이있는 경우 :

  • URI의 기본 유형 또는
  • 신체의 복잡한 유형

… 당신은 어떤 속성 (도 추가 할 필요가 없습니다 [FromBody]아니다 [FromUri]).

당신이있는 경우에, 원시 형몸을 , 당신은 추가 할 필요가 [FromBody]당신의 WebAPI 컨트롤러 방법에 원시 형식 매개 변수 앞에. (기본적으로 WebAPI는 HTTP 요청의 URI에서 기본 유형을 찾고 있기 때문입니다.)

또는 URI에 복잡한 유형 이 있으면을 추가해야합니다 . (기본적으로 WebAPI는 기본적으로 HTTP 요청 본문에서 복잡한 유형을 찾습니다.)[FromUri]

기본 유형 :

public class UsersController : ApiController
{
    // api/users
    public HttpResponseMessage Post([FromBody]int id)
    {

    }
    // api/users/id
    public HttpResponseMessage Post(int id)
    {

    }
}

복잡한 유형 :

public class UsersController : ApiController
{
    // api/users
    public HttpResponseMessage Post(User user)
    {

    }

    // api/users/user
    public HttpResponseMessage Post([FromUri]User user)
    {

    }
}

HTTP 요청에 하나의 매개 변수 만 보내면 작동합니다 . 여러 개를 보낼 때 다음과 같은 모든 매개 변수가있는 사용자 지정 모델 을 만들어야합니다.

public class MyModel
{
    public string MyProperty { get; set; }
    public string MyProperty2 { get; set; }
}

[Route("search")]
[HttpPost]
public async Task<dynamic> Search([FromBody] MyModel model)
{
    // model.MyProperty;
    // model.MyProperty2;
}

ASP.NET 웹 API의 매개 변수 바인딩에 대한 Microsoft 문서 에서 :

매개 변수에 [FromBody]가 있으면 Web API는 Content-Type 헤더를 사용하여 포맷터를 선택합니다. 이 예제에서 컨텐츠 유형은 “application / json”이고 요청 본문은 원시 JSON 문자열 (JSON 오브젝트가 아님)입니다. 메시지 본문에서 최대 하나의 매개 변수를 읽을 수 있습니다.

이것은 작동해야합니다 :

public HttpResponseMessage Post([FromBody] string name) { ... }

작동하지 않습니다.

// Caution: This won't work!    
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

이 규칙의 이유는 요청 본문이 한 번만 읽을 수있는 버퍼되지 않은 스트림에 저장 될 수 있기 때문입니다.


답변

위의 답변 외에도 ..

[FromUri]를 사용하여 querystring에서 매개 변수를 전달하는 대신 uri 매개 변수에서 복합 유형을 바인딩 할 수도 있습니다.

예를 들어

public class GeoPoint
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

[RoutePrefix("api/Values")]
public ValuesController : ApiController
{
    [Route("{Latitude}/{Longitude}")]
    public HttpResponseMessage Get([FromUri] GeoPoint location) { ... }
}

다음과 같이 호출 할 수 있습니다.

http://localhost/api/values/47.678558/-122.130989


답변

매개 변수에 [FromBody]가 있으면 Web API는 Content-Type 헤더를 사용하여 포맷터를 선택합니다. 이 예제에서 컨텐츠 유형은 “application / json”이고 요청 본문은 원시 JSON 문자열 (JSON 오브젝트가 아님)입니다.

메시지 본문에서 최대 하나의 매개 변수를 읽을 수 있습니다. 따라서 이것은 작동하지 않습니다.

 // Caution: Will not work!
public HttpResponseMessage Post([FromBody] int id, [FromBody] string name) { ... }

이 규칙의 이유는 요청 본문이 한 번만 읽을 수있는 버퍼되지 않은 스트림에 저장 될 수 있기 때문입니다.

자세한 내용은 웹 사이트를 참조하십시오 : http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api


답변