1

I have the very simple Azure HTTP triggered function that receives a POST with the data:

{
    "symbols": ["Azure1", "Azure2", "Azure3"]
}

And my Azure function is:

#r "Newtonsoft.Json"
using System.Net;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info("C# HTTP trigger function processed a request.");

    // parse query parameter
    string symbols = req.GetQueryNameValuePairs()
        .FirstOrDefault(q => string.Compare(q.Key, "symbol", true) == 0)
        .Value;

    // Get request body
    dynamic data = await req.Content.ReadAsAsync<object>();

    // Set name to query string or body data
    symbols = symbols ?? data?.symbols;

    return symbols == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")
        : req.CreateResponse(HttpStatusCode.OK, symbols, JsonMediaTypeFormatter.DefaultMediaType);
}

However, I am getting a 500 response with the error message: Cannot implicitly convert type 'Newtonsoft.Json.Linq.JArray' to 'string'. An explicit conversion exists (are you missing a cast?).

Does anyone see where I might be going wrong here? My expectation is that the function response would be:

["Azure1", "Azure2", "Azure3"]
Brett
  • 11,637
  • 34
  • 127
  • 213

1 Answers1

3

The error makes sense. You are declaring symbols as a string, but you later assign data?.symbols to it, which is an array. Hence the message Cannot implicitly convert type 'Newtonsoft.Json.Linq.JArray' to 'string'.

Unless you want to support passing data via query string, you should just get rid of that query string logic. e.g. try this:

#r "Newtonsoft.Json"
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using Newtonsoft.Json.Linq;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    dynamic data = await req.Content.ReadAsAsync<object>();
    JArray symbols = data?.symbols;

    return symbols == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass symbols in the body")
        : req.CreateResponse(HttpStatusCode.OK, symbols, JsonMediaTypeFormatter.DefaultMediaType);
}
David Ebbo
  • 42,443
  • 8
  • 103
  • 117
  • I find the default auto-generated C# function a bit confusing. It reads both query and body, uses `object` and `dynamic` - just not a good sample for beginners. Same goes for F#. – Mikhail Shilkov Nov 28 '17 at 06:54
  • Thanks @David. That did it. And Mikhail, I completely agree! – Brett Nov 28 '17 at 15:45
  • A bit of a side topic from the type conversion issue. It could be that the default template is confusing indeed. It tries to demonstrates multiple techniques, which is why it does both query string and body. But that does make it more complex. We can take this to https://github.com/Azure/azure-webjobs-sdk-templates/issues for further discussions. – David Ebbo Nov 28 '17 at 18:36