25

ASP.Net 웹 API의 모델 바인딩이 MVC에서 지원하는 동일한 최소 수준의 기능을 사용하여 바인딩을 지원한다고 생각했습니다. 나는 그것을 요구하고있어ASP.Net 웹 API 모델 바인딩이 MVC 3 에서처럼 작동하지 않습니다.

public class WordsController : ApiController 
{ 
    private string[] _words = new [] { "apple", "ball", "cat", "dog" }; 

    public IEnumerable<string> Get(SearchModel searchSearchModel) 
    { 
     return _words 
      .Where(w => w.Contains(searchSearchModel.Search)) 
      .Take(searchSearchModel.Max); 
    } 
} 

public class SearchModel 
{ 
    public string Search { get; set; } 
    public int Max { get; set; } 
} 

:

는 다음과 같은 컨트롤러를 가지고는 MVC에서와 같이

http://localhost:62855/api/words?search=a&max=2 

불행하게도 모델이 결합하지 않습니다. 왜 예상대로 바인딩이되지 않습니까? 내 응용 프로그램에는 다양한 모델 유형이 많이 있습니다. MVC 에서처럼 바인딩이 작동하면 좋을 것입니다.

+0

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web.Http; using System.Threading.Tasks; using Newtonsoft.Json; namespace Combined.Controllers // This is an ASP.NET Web Api 2 Story { // Paste the following string in your browser -- the goal is to convert the last name to lower case // The return the result to the browser--You cant click on this one. This is all Model based. No Primitives. // It is on the Local IIS--not IIS Express. This can be set in Project->Properties=>Web http://localhost/Combined with a "Create Virtual Directory" // http://localhost/Combined/api/Combined?FirstName=JIM&LastName=LENNANE // Paste this in your browser After the Default Page it displayed // public class CombinedController : ApiController { // GET: api/Combined This handels a simple Query String request from a Browser // What is important here is that populating the model is from the URI values NOT the body which is hidden public Task<HttpResponseMessage> Get([FromUri]FromBrowserModel fromBrowser) { // // The Client looks at the query string pairs from the Browser // Then gets them ready to send to the server // RequestToServerModel requestToServerModel = new RequestToServerModel(); requestToServerModel.FirstName = fromBrowser.FirstName; requestToServerModel.LastName = fromBrowser.LastName; // Now the Client send the Request to the Server async and everyone awaits the Response Task<HttpResponseMessage> response = PostAsyncToApi2Server("http://localhost/Combined/api/Combined", requestToServerModel); return response; // The response from the Server should be sent back to the Browser from here. } async Task<HttpResponseMessage> PostAsyncToApi2Server(string uri, RequestToServerModel requestToServerModel) { using (var client = new HttpClient()) { // Here the Method waits for the Request to the Server to complete return await client.PostAsJsonAsync(uri, requestToServerModel) .ContinueWith((postTask) => postTask.Result.EnsureSuccessStatusCode()); } } // POST: api/Combined This Handles the Inbound Post Request from the Client // NOTICE THE [FromBody] Annotation. This is the key to extraction the model from the Body of the Post Request-- not the Uri ae in [FromUri] // Also notice that there are no Async methods here. Not required, async would probably work also. // public HttpResponseMessage Post([FromBody]RequestToServerModel fromClient) { // // Respond to an HttpClient request Synchronously // The model is serialised into Json by specifying the Formatter Configuration.Formatters.JsonFormatter // Prep the outbound response ResponseToClientModel responseToClient = new ResponseToClientModel(); // // The conversion to lower case is done here using the Request Body Data Model // responseToClient.FirstName = fromClient.FirstName.ToLower(); responseToClient.LastName = fromClient.LastName.ToLower(); // // The Client should be waiting patiently for this result // using (HttpResponseMessage response = new HttpResponseMessage()) { return this.Request.CreateResponse(HttpStatusCode.Created, responseToClient, Configuration.Formatters.JsonFormatter); // Respond only with the Status and the Model } } public class FromBrowserModel { public string FirstName { get; set; } public string LastName { get; set; } } public class RequestToServerModel { public string FirstName { get; set; } public string LastName { get; set; } } public class ResponseToClientModel { public string FirstName { get; set; } public string LastName { get; set; } } } }

아마 [1] 문제,이 [포스트] 당신을 도와줍니다. [1] : http://stackoverflow.com/questions/12072277/reading-fromuri-and-frombody-at-the-same-time – Cagdas

답변

27

이것 좀 봐 : How WebAPI does Parameter Binding

당신은 너무처럼 복잡한 매개 변수를 장식해야합니다

public IEnumerable<string> Get([FromUri] SearchModel searchSearchModel) 

또는

public IEnumerable<string> Get([ModelBinder] SearchModel searchSearchModel) 
1

내가 할 전체 웹 API (2)를 발견했다 "Gotchas"가 많이있는 어려운 학습 곡선 나는이 풍부한 제품을 제공하는 많은 불가사의 한 뉘앙스를 다루는 몇 가지 핵심 서적을 읽었습니다. 하지만 기본적으로 기능의 장점을 최대한 활용할 수있는 핵심 기능이 있어야한다고 생각했습니다. 그래서 나는 4 가지 직선 과제를 수행하기 시작했다. 1. 브라우저에서 Api2 클라이언트로 쿼리 문자열을 수락하고 간단한 .NET 모델을 채 웁니다. 2. 클라이언트가 클라이언트에서 POST 요청에 사소한 변환을 수행 3. 서버가 이전 모델에서 추출 된 JSON에 코딩되는 API2 서버에 비동기 포스트를 제출하게한다. 4. 모든 정보를 다시 브라우저에 전달합니다. 이거 야.

관련 문제