Die ASP.Net-Web-API-Modellbindung funktioniert nicht wie in MVC 3

Translate

Ich hatte den Eindruck, dass die Modellbindung in der ASP.Net-Web-API die Bindung mit demselben von MVC unterstützten Mindestmaß an Funktionalität unterstützen sollte.

Nehmen Sie den 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 fordere es an mit:

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

Leider bindet das Modell nicht wie in MVC. Warum ist das nicht verbindlich, wie ich es erwarten würde? Ich werde viele verschiedene Modelltypen in meiner Anwendung haben. Es wäre schön, wenn das Binden einfach funktionieren würde, wie es in MVC der Fall ist.

This question and all comments follow the "Attribution Required."

Alle Antworten

Translate

Schau dir das an:Wie WebAPI die Parameterbindung durchführt

Sie müssen Ihren komplexen Parameter folgendermaßen dekorieren:

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

OR

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

Ich habe festgestellt, dass die gesamte Web-API 2 eine schwierige Lernkurve mit vielen "Fallstricken" ist. Ich habe einige der Schlüsselbücher gelesen, die viele arkane Nuancen dieses reichhaltigen Produktangebots abdecken. Aber im Grunde dachte ich, dass es einige Kernfunktionen geben muss, die die besten Funktionen nutzen können. Also machte ich mich daran, vier einfache Aufgaben zu erledigen. 1. Akzeptieren Sie eine Abfragezeichenfolge aus einem Browser in einen Api2-Client und füllen Sie ein einfaches .NET-Modell. 2. Lassen Sie den Kunden eineasynchronPost auf einem in JSON codierten Api2-Server, der aus dem vorherigen Modell 3 extrahiert wurde. Lassen Sie den Server eine triviale Konvertierung der Post-Anfrage 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; }
        }

        
    }
}
Quelle
Leave a Reply
You must be logged in to post a answer.
Über den Autor