tutorial - El enlace de modelo de ASP.Net Web API no funciona como lo hace en MVC 3
web api rest c# (2)
Eche un vistazo a esto: cómo WebAPI enlaza los parámetros
Necesitas decorar tu parámetro complejo así:
public IEnumerable<string> Get([FromUri] SearchModel searchSearchModel)
O
public IEnumerable<string> Get([ModelBinder] SearchModel searchSearchModel)
Tenía la impresión de que se suponía que el enlace modelo en ASP.Net Web API admitía el enlace con el mismo nivel mínimo de funcionalidad admitido por MVC.
Tome el siguiente controlador:
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; }
}
Lo estoy solicitando con:
http://localhost:62855/api/words?search=a&max=2
Lamentablemente, el modelo no se une como lo haría en MVC. ¿Por qué esto no es vinculante como era de esperar? Tendré muchos tipos de modelos diferentes en mi aplicación. Sería bueno si el enlace solo funcionara, como lo hace en MVC.
He descubierto que toda la Web API 2 es una curva de aprendizaje difícil con muchos "errores". He leído algunos de los libros clave que cubren muchos de los misterios de esta oferta de productos. Pero básicamente, pensé que debía haber alguna funcionalidad central que pudiera aprovechar las mejores características. Entonces, me propuse hacer cuatro tareas sencillas. 1. Acepte una cadena de consulta, desde un navegador, a un Cliente Api2 y rellene un modelo .NET simple. 2. Haga que el cliente envíe una publicación asíncrona a un servidor Api2 codificado en JSON extraído del modelo anterior 3. Haga que el servidor realice una conversión trivial en la solicitud postal del cliente. 4. Pásalo todo de vuelta al navegador. Eso es todo.
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; }
}
}
}