Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to receive dynamic data in Web API controller Post method

jqgrid posts json data in POST request buffer as

{"headerData": {
    "Tasudok": "134",
    "Kuupaev": "2015-11-23",
    "Dokumnr": "135319"
   },


"rowData": {
  "Toode":"",
  "Kogus":"0.0000",
  "Nimetus":"öäölä<a",
  "_rowsum":"0.00",
  "Id":"1639",
  "Dokumnr":"135319",
  "_oper":"edit",
  "_rowid":"1639"
  }
}

Data is posted to ASP.NET MVC4 Web API using URL like API/Entity/someid?culture=en&layout=1 with default routing.

headerData and rowData value properties are defined in runtime and can vary.

For example in some call rowData may contain additional properties and some rowData properties may be missing.

culture and layout query string paramaters are optional.

How to receive parameters in WebAPI controller ?

I tried

public class EntityController : APIController
{

public class PostParams {
    public string culture { get; set; }
    public int? layout { get; set; }
    }

    public HttpResponseMessage Post(string id, 
      [FromUri]PostParams optionalParams,
      [FromBody]IList<NameValue> headerData,
      [FromBody]IList<NameValue> rowData )
    { ... }


public class NameValue
{
    public string name, value;
}
}

But headerData and rowData are empty. How to get all parameters?

like image 374
Andrus Avatar asked Nov 25 '15 19:11

Andrus


People also ask

Can we have multiple post methods in controller?

Similarly, you can add any number of POST, GET, PUT, DELETE methods in one controller.

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 pass data from MVC controller to Web API?

From the start window select "Installed" -> "Visual C#" -> "Web". Select "ASP.NET MVC4 Web Application" and click on the "OK" button. From the "MVC4 Project" window select "Web API". Click on the "OK" button.


1 Answers

If the structure of the JSON does not change

Having this will permit you to send the body like the one you provided at a url like API/Entity/someid?culture=en&layout=1.

To specify optional query parameter in your controller route, give them a default value like:

public class EntityController : APIController
{
    public HttpResponseMessage Post([FromUri]string culture="EN", [FromUri]int layout=1, YourBody body )
    { ... }
}

If YourBody is always like the one you mentionned, something like this should be deserialized automatically:

public class YourBody
{
    public Dictionary<string, string> HeaderData {get; set;}
    public Dictionary<string, string> RowData{get; set;}
}

and would give you full access to any element of the body.

If the structure of the JSON can change

Something like this would permit the receive any kind of json:

public HttpResponseMessage  Post([FromBody]JToken body)
{
    // Process the body
    return ...
}

You will need some extra validation since no object deserialization will be made. The only think you'll know is that your body is a JSON.

You therefore may want to parse it to see if it looks like what you are expecting. See that post about how to access element of a JSON with JToken.

For instance, you could do something like the following to handle a changing body content and still handle optional query parameters of your route :

public HttpResponseMessagePost([FromBody]JToken body, [FromUri]string culture="EN", [FromUri]int layout=1)
{
    JObject headerData= body["headerData"].Value<JObject>();
    JObject headerData= body["rowData"].Value<JObject>();
    return ...;
}

You may also read this about other alternatives for posting raw data to a webapi controller.

like image 98
plog17 Avatar answered Sep 21 '22 13:09

plog17