ASP.Net Web API model binding not working like it does in MVC 3

老子叫甜甜 提交于 2019-12-03 22:13:37

Take a look at this: How WebAPI does Parameter Binding

You need to decorate your complex parameter like so:

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

OR

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

I have found the entire Web API 2 to be a difficult learning curve with lots of "Gotchas" I have read a few of the key books that cover many arcane nuances of this rich product offering. But basically, I thought there must be some core functionality that could take advantage of the best of the features. So, I set out to do four straight forward tasks. 1. Accept a query string, from a browser, into an Api2 Client and populate a simple .NET model. 2. Have the Client submit an async Post to an Api2 Server encoded in JSON extracted from the prior Model 3. Have the Server do a trivial conversion on the Post Request from the Client. 4. Pass it all back up to the Browser. This is it.

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

        
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!