5

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?

Andrus
  • 26,339
  • 60
  • 204
  • 378

1 Answers1

6

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.

Community
  • 1
  • 1
plog17
  • 832
  • 8
  • 23
  • First post method signature causes compile error `Optional parameters must appear after all required parameters` – Andrus Nov 26 '15 at 08:16
  • Your compiler is right ! I'll update my post (I wrote that code in a text editor, no access to VS nor a compiler) And what do you get if you do what the compiler tells you ? Does it compiles ? – plog17 Nov 26 '15 at 12:54
  • Yes, it compiles then. Great answer and great link, thank you. – Andrus Nov 26 '15 at 13:01
  • If it does what you wanted, I thank you in advance to mark my answer as accepted. If there is still some issue with my answer let me know and I will update it ! – plog17 Nov 26 '15 at 13:03
  • I tried first signature. Both `headerData` and `rowData` have null values in controller. How to receive values for them ? – Andrus Nov 26 '15 at 16:36
  • I posted this in http://stackoverflow.com/questions/33943604/how-to-receive-dynamic-objects-in-webapi-controller – Andrus Nov 26 '15 at 16:48
  • I think I missed public for both members of YourBody. I answered your question at the link you provided. Everything should work fine now ! – plog17 Nov 26 '15 at 17:17
  • I tried but headerData is empty. I posted it in http://stackoverflow.com/questions/36206340/how-to-post-form-data-to- api-controller – Andrus Mar 24 '16 at 17:28