简体   繁体   中英

Web API and application/x-www-form-urlencoded JSON

I am working on a webhook that receives data from a third party source. Unfortunately, they post data to me in a very strange and improper way. Nonetheless, this is what I have to deal with. They are sending data with a content type of application/x-www-form-urlencoded in the following format:

randomJsonObjects: 
[
  {
    "email": "john@example.com",
    "timestamp": 1337197600,
    "id": "55555",
  },
  {
    "email": "johnny@example.com",
    "timestamp": 1337547600,
    "id": "44444",
  }
]

Of course that is not valid JSON, but it's not being sent as such either. My problem is I can not get Web API to parse this out correctly. Generally with JSON I just use this as my controller:

public HttpResponseMessage Create(List<MyObject> jsonObjects)

But that doesn't work. I've tried numerous options and always ends up with null values.

You have to use newtonsoft.json

There are able to unserialize anonymous objects and pretty much every json stuff go check out : http://json.codeplex.com/

for you case i think a simple line like this will do the trick:

List<dynamic> randomJsonObjects= JsonConvert.DeserializeObject<List<dynamic>>(randomJsonObjects);

the problem si that your code start by randomJsonObjects: so you just have to remove it and after call the line above. or add the { } to transform it as an object

The data-structure that is being encoded in application/x-www-form-urlencoded closely resembles NameValueCollection .

Capture the query string and try to parse it using HttpUtility.ParseQueryString . In addition, this SO might help

Try and see if the following fits your needs...here I am making a big assumption that the format for the request content would be always like randomJsonObjects:[.....] and hence I try to first parse to see if its a valid json and if not I am adding a wrapping { , } characters.

Of course this can be improved so that you always handle some type of parameters (ex: AddressBook in this case) specially and so you might want to write the following logic into something like HttpParameterBinding in which case wherever this parameter is used on the action, the following workaround would be used...

public async Task Post()
{
    bool validJson = false;
    string originalData = await Request.Content.ReadAsStringAsync();

    try
    {
        JObject jo = JObject.Parse(originalData);
        validJson = true;
    }
    catch (JsonReaderException)
    {
    }

    string modifiedData = null;
    if (!validJson)
    {
        modifiedData = "{" + originalData + "}";
    }
    else
    {
        modifiedData = originalData;
    }

    AddressBook book = JsonConvert.DeserializeObject<AddressBook>(modifiedData);

    //TODO: do something with the book
}

public class AddressBook
{
    [JsonProperty("randomJsonObjects")]
    public IEnumerable<ContactInfo> Contacts { get; set; }
}

public class ContactInfo
{
    public string Email { get; set; }
    public long TimeStamp { get; set; }
    public string Id { get; set; }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM