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

时间:2014-04-07 15:55:28

标签: c# json api asp.net-web-api

我正在开发一个从第三方来源接收数据的webhook。不幸的是,他们以非常奇怪和不正当的方式向我发布数据。尽管如此,这是我必须要处理的。他们使用以下格式发送内容类型为application/x-www-form-urlencoded的数据:

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

当然,这不是有效的JSON,但它也不是这样发送的。我的问题是我无法让Web API正确地解析它。通常使用JSON我只使用它作为我的控制器:

public HttpResponseMessage Create(List<MyObject> jsonObjects)

但这并不奏效。我尝试过很多选项,但总是以空值结束。

3 个答案:

答案 0 :(得分:0)

你必须使用newtonsoft.json

能够反序列化匿名对象和几乎每个json的东西 去看看:http://json.codeplex.com/

对于你的情况,我认为像这样的简单线条可以解决这个问题:

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

你的代码以randomJsonObjects开头的问题:所以你只需要删除它并在调用上面的行之后。 或添加{}将其转换为对象

答案 1 :(得分:0)

application/x-www-form-urlencoded中编码的数据结构与NameValueCollection非常相似。

捕获查询字符串并尝试使用HttpUtility.ParseQueryString解析它。此外,this SO可能会有所帮助

答案 2 :(得分:0)

尝试看看以下内容是否符合您的需求......在这里我做了一个很大的假设,即请求内容的格式总是像randomJsonObjects:[.....],因此我尝试首先解析它是否是有效的json,如果不是,我正在添加包裹{}个字符。

当然这可以改进,以便你总是特别处理某些类型的参数(在这种情况下为例如AddressBook),因此您可能希望将以下逻辑编写为类似HttpParameterBinding的内容无论在该操作上使用此参数的哪种情况,都将使用以下解决方法......

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