FromBody와 FromUri를 지정해야하는 이유는 무엇입니까?


157

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

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


11
[FromBody] 주석을 사용하는 것이 유용한 경우에 대한 힌트를 제공하기 위해 : 예를 들어 사용자 이름 / 암호와 같은 정적 자격 증명을 URL 내에 인코딩 된 매개 변수로 보내는 것은 좋지 않습니다. SSL 암호화로 인해 타사가 URL 내의 매개 변수에 대한 읽기 액세스 권한을 얻지 못할 수도 있지만 이러한 자격 증명이 브라우저 로그에 저장되어 동등하게 요구 될 수 있으므로 여전히 좋지 않습니다. 이 경우 [FromBody] 어노테이션을 사용하여 HTTP 메시지 본문에 매개 변수를 강제로 저장하여 높음
Chris

답변:


193

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를"구글 경우 웹은.


2
@ user3510527 : 기본 동작을 따르는 한 원하지 않는 경우 이러한 속성을 사용할 필요가 없습니다. 기본 동작을 변경하려면 해당 동작을 사용해야합니다.
djikay

1
기본 동작을 수행하는 경우 왜 ovveride가 필요한지, 그리고이 속성을 언급하면 ​​어떤 이점이 있습니까?
Rajneesh

1
@ user3510527 무시할 필요 가 없습니다 . 기본 동작 만 사용할 수 있습니다. 누군가 재정의하려는 예는 기본적으로 URI에서 찾을 것으로 예상하기 때문에 요청 본문에 간단한 정수를 제공하려는 경우입니다. 기본적으로 원하는 경우 기본 동작을 그대로 두거나 무시할 수 있습니다. 옵션입니다. 혼란이 무엇인지 이해할 수 없습니다.
djikay

양식 속성을 사용하면 내부 작업 프로세스를 알고 싶기 때문에 직접 값을 얻거나 uri 또는 formbody를 확인하지 않습니다 ...
Rajneesh

7
하나라는 속성을 만들 수 있는지 궁금해 JustGetIt같은 여러 속성을 추가하는 같은 목적으로 역할 [FromBody, FromQuery]
머핀 맨

93

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

  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) { ... }

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


5
"대부분의 매개 변수는 메시지 본문에서 읽을 수 있습니다"는 특히 유용한 정보였습니다.
Ryan

15

위의 답변 외에도 ..

[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

12

매개 변수에 [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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.