Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET WEB API not binding to dynamic object on POST

If have the following Api Controller ... using StrutureMap for the DI ...

using System;
using System.Dynamic;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using IdentityService.Domain;
using IdentityService.Domain.Contracts;
using IdentityService.Domain.Models;

namespace IdentityService.Controllers
{
    public class AccountController : ApiController
    {
        private readonly IRepository<Client> _clientRepository;
        private readonly IRepository<RelyingParty> _relyingPartyRepository;
        private readonly IRepository<Token> _tokenRepository;

        public AccountController(
            IRepository<Client> clientRepository,
            IRepository<RelyingParty> relyingPartyRepository,
            IRepository<Token> tokenRepository)
        {
            _clientRepository = clientRepository;
            _relyingPartyRepository = relyingPartyRepository;
            _tokenRepository = tokenRepository;
        }

        public HttpResponseMessage Post(
            [FromBody] dynamic data)
        {
            dynamic result = new ExpandoObject();

            try
            {
                var clientAuthenticator = new ClientAuthenticator(
                    _clientRepository,
                    _relyingPartyRepository,
                    _tokenRepository);

                Token token;
                clientAuthenticator.Authenticate(
                    data.Key,
                    data.ChecksumValue,
                    data.Checksum,
                    data.Name,
                    data.Password,
                    out token);

                result.Token = token;
            }
            catch (Exception ex)
            {
                result.ErrorCode = ex.GetType().ToString();
                result.ErrorMessage = ex.GetBaseException().Message;
            }

            return this.Request.CreateResponse(HttpStatusCode.OK, (ExpandoObject)result);
        }
    }
}

Using Fiddler, I am make the following post:

POST http://localhost:54029/api/account HTTP/1.1
User-Agent: Fiddler
Host: localhost:54029
Content-Type: "application/json"
Content-Length: 218

{
    "Key": "7d42276d3c3954716c672543385b575836472f5d543d7776205627413a",
    "ChecksumValue": "127.0.0.1",
    "Checksum": "ao4Ei77BaX1/iMZMTAJxWzt4fxc=",
    "Name": "USER_NAME",
    "Password": "PASSWORD"
}

Any idea why my data would be null? I have tried switching to JObject, with no success. All the examples I have found makes me think this should work.

Here is the complete response:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcY29kZS1tYXR0cnVtYVx0YWxrLWF1dGhlbnRpY2F0aW9uLXNlcnZlclxJZGVudGl0eVNlcnZpY2VcYXBpXGFjY291bnQ=?=
X-Powered-By: ASP.NET
Date: Mon, 27 May 2013 13:59:45 GMT
Content-Length: 137

{"ErrorCode":"Microsoft.CSharp.RuntimeBinder.RuntimeBinderException","ErrorMessage":"Cannot perform runtime binding on a null reference"}

Any help would be much appreciated!

Update

I tried just a simple example, like:

public async Task<dynamic> Post(dynamic data)
{
     var body = await Request.Content.ReadAsStringAsync();

     return data;
}

The parameter data is still null, but I can see the values in body.

like image 924
mattruma Avatar asked May 27 '13 13:05

mattruma


People also ask

What is FromBody and FromUri in Web API?

The [FromUri] attribute is prefixed to the parameter to specify that the value should be read from the URI of the request, and the [FromBody] attribute is used to specify that the value should be read from the body of the request.

How do I use FromUri in Web API?

Using [FromUri] To force Web API to read a complex type from the URI, add the [FromUri] attribute to the parameter. The following example defines a GeoPoint type, along with a controller method that gets the GeoPoint from the URI.

What is FromBody C#?

The [FromBody] attribute which inherits ParameterBindingAttribute class is used to populate a parameter and its properties from the body of an HTTP request. The ASP.NET runtime delegates the responsibility of reading the body to an input formatter.

What is parameter binding in asp net web API?

The Parameter Binding in ASP.NET Web API means how the Web API Framework binds the incoming HTTP request data (query string or request body) to the parameters of an action method of a Web API controller. The ASP.NET Web API action methods can take one or more parameters of different types.


2 Answers

Remove the quotes from "application/json".

Content-Type: application/json
like image 127
Matt Houser Avatar answered Sep 18 '22 16:09

Matt Houser


In an MVC 6 controller (which extends from Controller and not ApiController) the following does work (with report being JSON) :

    [HttpPost("[action]")]
    public void RunReport([FromBody]dynamic report)
    {
        ....
    }

Updated: For MVC 5 this is what I use

    [HttpPost]
    public async Task<HttpResponseMessage> FBLogin(Newtonsoft.Json.Linq.JObject jObject)
    {
        dynamic data = (dynamic)jObject;

        string accessToken = data.accessToken;
        ...
     }

Where the JSON payload is :

 '{accessToken: "EAAJF9eVIKOsBABdKVNOLJyfyCnnkrl8mlW2crgZC1NYsDqgq9ZBIZC......" }'
like image 40
Simon_Weaver Avatar answered Sep 17 '22 16:09

Simon_Weaver