Jason Shave
Jason Shave

Reputation: 2672

Exception deserializing JSON with Newtonsoft sent by CURL to Azure Function

When posting to my API using CURL the syntax I'm using is:

curl -H "Content-Type:application/json" -X POST -d '{"domainName":"fabrikam.onmicrosoft.com","apiKey":"980709a87df09a78dsf90a8s7f"}' http://localhost:7071/api/getnodedata

My web API receives the request via:

dynamic data = await req.Content.ReadAsAsync<object>();
NodeModel nodeData = Newtonsoft.Json.JsonConvert.DeserializeObject<NodeModel>(data);

My class is simple:

public class NodeModel : TableEntity
{
    public string DomainName { get; set; }
    public string ApiKey { get; set; }
}

public static NodeModel(string DomainName, string ApiKey)
{
    this.PartitionKey = DomainName;
    this.RowKey = ApiKey;
}

Inspecting data gives me '{domainName:fabrikam.onmicrosoft.com,apiKey:980709a87df09a78dsf90a8s7f}' which looks okay except for the missing double quotes around each key/value pair. CURL is removing the double-quotes before sending it (as verified using Fiddler trace).

I get an exception in my func.exe local application as follows:

mscorlib: Exception while executing function: GetNodeData. Newtonsoft.Json: Error parsing boolean value. Path 'domainName'

I've tried:

  1. Spaces between the key/values
  2. Single quotes wrapping the keys(s)
  3. Single quotes wrapping the value(s)
  4. Researching Newtonsoft website for correct syntax
  5. Researching this site for other examples (which don't seem to be any different from what I'm doing).

Any suggestions or instructions for using another tool? I have Fiddler too but haven't used it for POSTing data to a service.

Upvotes: 2

Views: 557

Answers (2)

DavidG
DavidG

Reputation: 119156

Summarising the comments in an answer...

  1. Using Fiddler - this is a great tool, but it works as a proxy server on your machines. Various tools will not respect system settings and curl is one of those. The .NET HttpClient is the same. So you need to tell it to use the proxy with the --proxy (or -x for short option:

    curl -H "Content-Type: application/json" -X POST -d '...snip...' http://localhost:7071/api/getnodedata -x http://localhost:8888
    
  2. curl is stripping out the double quotes. To get around that you need to use double quote to surround your data and escape inner quotes with a backslash:

    -d "{\"domainName\": \"fabrikam.onmicrosoft.com\", \"apiKey\": \"980709a87df09a78dsf90a8s7f\"}"
    
  3. I wouldn't generally recommend using curl to test an API. It's a great tool but, as you have seen, awkward to use. Instead I recommend using Postman.

  4. Bonus! Your C# code is a little skewy too. Either read the data as a string and pass to JSON.Net:

    string data = await req.Content.ReadAsStringAsync();
    NodeModel nodeData = Newtonsoft.Json.JsonConvert.DeserializeObject<NodeModel>(data);
    

    Or, even better, let the extension you're already using do the work for you:

    NodeModel nodeData = await req.Content.ReadAsAsync<NodeModel>();
    

Upvotes: 2

Mauricio Atanache
Mauricio Atanache

Reputation: 2581

Try this :

curl -H "Content-Type:application/json" -X POST -d "{\"domainName\":\"fabrikam.onmicrosoft.com\",\"apiKey\":\"980709a87df09a78dsf90a8s7f\"}" 
 http://localhost:7071/api/getnodedata

Upvotes: 1

Related Questions