25

Miałem wrażenie, że powiązanie modelu w ASP.Net Web API miało wspierać wiązanie z tym samym minimalnym poziomem funkcjonalności obsługiwanym przez MVC.Wiązanie modelu ASP.Net Web API nie działa tak, jak w MVC 3

Weźmy następujący Kontroler:

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; } 
} 

mam go z prośbą:

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

Niestety model nie wiąże się, jak to będzie w MVC. Dlaczego nie jest to wiążące, czego bym się spodziewał? W mojej aplikacji będę miał wiele różnych typów modeli. Byłoby miło, gdyby bindowanie zadziałało, tak jak w MVC.

+0

Może pomóc, ten [post] [1] problem. [1]: http://stackoverflow.com/questions/12072277/reading-fromuri-and-frombody-at-the-same-time – Cagdas

Odpowiedz

27

Spójrz na to: How WebAPI does Parameter Binding

trzeba ozdobić swój skomplikowany parametr tak:

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

LUB

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

znalazłem całą Web API 2, aby być trudna krzywa uczenia się z dużą ilością "Gotchas" Przeczytałem kilka kluczowych książek, które zawierają wiele tajemniczych niuansów tej bogatej oferty produktów. Ale w zasadzie myślałem, że musi istnieć podstawowa funkcjonalność, która mogłaby wykorzystać najlepsze cechy. Tak więc postanowiłem wykonać cztery proste zadania. 1. Zaakceptuj ciąg zapytania, z przeglądarki, do klienta Api2 i zapełnij prosty model .NET. 2. Poproś klienta o przesłanie asynchronicznej Opublikuj na serwerze Api2 zakodowanym w JSON wyodrębnionym z poprzedniego Modelu 3. Niech Serwer dokona trywialnej konwersji na Żądanie Pocztowe od Klienta. 4. Przekaż wszystkie dane do przeglądarki. To jest to.

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; } 
 
     } 
 

 
     
 
    } 
 
}

Powiązane problemy