25

Ich hatte den Eindruck, dass Modellbindung in der ASP.Net-Web-API Bindung mit der gleichen Mindestfunktionalität unterstützen sollte, die von MVC unterstützt wird.ASP.Net Web API-Modellbindung funktioniert nicht wie in MVC 3

Nehmen Sie die folgenden Controller:

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

ich es mit anfordernden bin:

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

Leider ist das Modell nicht bindet, wie es wäre in MVC. Warum ist das nicht bindend, wie ich es erwarten würde? Ich werde viele verschiedene Modelltypen in meiner Anwendung haben. Es wäre schön, wenn die Bindung genauso funktioniert wie in MVC.

+0

Ihnen vielleicht helfen, diese [post] [1] Problem. [1]: http://stackoverflow.com/questions/12072277/reading-fromuri-and-frombody-at-the-same-time – Cagdas

Antwort

27

Werfen Sie einen Blick auf diese: How WebAPI does Parameter Binding

Sie benötigen komplexe Parameter wie so dekorieren:

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

ODER

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

ich die gesamte Web gefunden API haben 2 zu sein Eine schwierige Lernkurve mit vielen "Gotchas" Ich habe einige der Schlüsselbücher gelesen, die viele arkane Nuancen dieses reichen Produktangebots abdecken. Aber im Grunde dachte ich, dass es eine Kernfunktionalität geben muss, die die besten Funktionen nutzen könnte. Also machte ich mich auf den Weg, vier Aufgaben zu erledigen. 1. Übernehmen Sie eine Abfragezeichenfolge von einem Browser in einen Api2-Client und füllen Sie ein einfaches .NET-Modell. 2. Lassen Sie den Client eine asynchrone Post an einen Api2-Server senden, der in JSON codiert ist, das aus dem vorherigen Modell extrahiert wurde. 3. Lassen Sie den Server eine triviale Konvertierung der Postanforderung vom Client durchführen. 4. Übergeben Sie alles wieder an den Browser. Das ist es.

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

 
     
 
    } 
 
}

Verwandte Themen