Как вернуть JSON из функции Azure

Я играю с Azure Functions. Тем не менее, я чувствую, что я в тупике на что-то довольно простое. Я пытаюсь выяснить, как вернуть базовый JSON. Я не уверен, как создать JSON и вернуть его к моему запросу.

Когда-то я создавал объект, заполнял его свойства и сериализовал его. Итак, я начал по этому пути:

#r "Newtonsoft.Json"

using System.Net;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    log.Info($"Running Function");    
    try {      
      log.Info($"Function ran");

      var myJSON = GetJson();

      // I want myJSON to look like:
      // {
      //   firstName:'John',
      //   lastName: 'Doe',
      //   orders: [
      //     { id:1, description:'...' },
      //     ...
      //   ]
      // }
      return ?;
    } catch (Exception ex) {
        // TODO: Return/log exception
        return null;
    }
}

public static ? GetJson() 
{
  var person = new Person();
  person.FirstName = "John";
  person.LastName = "Doe";

  person.Orders = new List<Order>();
  person.Orders.Add(new Order() { Id=1, Description="..." });

  ?
}

public class Person 
{
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public List<Order> Orders { get; set; }
}

public class Order
{
  public int Id { get; set; }
  public string Description { get; set; }
}

Тем не менее, я полностью зациклен на процессе сериализации и возврата. Предположим, я привык возвращать JSON в ASP.NET MVC, где все является Action

Ответ 1

Здесь приведен полный пример функции Azure, возвращающей правильно отформатированный объект JSON вместо XML:

#r "Newtonsoft.Json"
using System.Net;
using Newtonsoft.Json;
using System.Text;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    var myObj = new {name = "thomas", location = "Denver"};
    var jsonToReturn = JsonConvert.SerializeObject(myObj);

    return new HttpResponseMessage(HttpStatusCode.OK) {
        Content = new StringContent(jsonToReturn, Encoding.UTF8, "application/json")
    };
}

Перейдите к конечной точке в браузере, и вы увидите:

{
  "name": "thomas",
  "location": "Denver"
}

Ответ 2

JSON довольно прост, библиотека Newtonsoft.Json - это специальный случай. Вы можете включить его, добавив это в начало файла script:

#r "Newtonsoft.Json"

using Newtonsoft.Json;

Тогда ваша функция будет выглядеть следующим образом:

public static string GetJson() 
{
  var person = new Person();
  person.FirstName = "John";
  person.LastName = "Doe";

  person.Orders = new List<Order>();
  person.Orders.Add(new Order() { Id=1, Description="..." });

  return JsonConvert.SerializeObject(person);
}

Ответ 3

Вы можете взять req из

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)

и создайте ответ, используя

return req.CreateResponse(HttpStatusCode.OK, json, "application/json");

или любой другой перегрузки в сборке System.Web.Http.

Дополнительная информация о docs.microsoft.com

Ответ 4

Вы можете изменить подпись метода на:

public static async Task<object> Run(HttpRequestMessage req, TraceWriter log)

и это позволит возвращать данные JSON.

Ответ 5

Похоже, что этого можно добиться, используя только тип медиафайла "application/json", без необходимости явно сериализовать Person с помощью Newtonsoft.Json.

Вот полный рабочий пример, который показывает в Chrome как:

{"FirstName":"John","LastName":"Doe","Orders":[{"Id":1,"Description":"..."}]}

Код приведен ниже:

[FunctionName("StackOverflowReturnJson")]
    public static HttpResponseMessage Run([HttpTrigger("get", "post", Route = "StackOverflowReturnJson")]HttpRequestMessage req, TraceWriter log)
    {
        log.Info($"Running Function");
        try
        {
            log.Info($"Function ran");

            var myJSON = GetJson();  // Note: this actually returns an instance of 'Person' 

            // I want myJSON to look like:
            // {
            //   firstName:'John',
            //   lastName: 'Doe',
            //   orders: [
            //     { id:1, description:'...' },
            //     ...
            //   ]
            // }
            var response = req.CreateResponse(HttpStatusCode.OK, myJSON, JsonMediaTypeFormatter.DefaultMediaType); // DefaultMediaType = "application/json" does the 'trick'
            return response;
        }
        catch (Exception ex)
        {
            // TODO: Return/log exception
            return null;
        }
    }

    public static Person GetJson()
    {
        var person = new Person();
        person.FirstName = "John";
        person.LastName = "Doe";

        person.Orders = new List<Order>();
        person.Orders.Add(new Order() { Id = 1, Description = "..." });

        return person;
    }

    public class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public List<Order> Orders { get; set; }
    }

    public class Order
    {
        public int Id { get; set; }
        public string Description { get; set; }
    }

Ответ 6

У меня была аналогичная проблема, и это, казалось, было самым популярным сообщением без ответа. После определения того, что node делает ниже, должно работать и дать вам именно то, что вам нужно. Другие примеры по-прежнему возвращают строковое представление, которое возвращает JSON.

Не забудьте объявить использование System.Text; а также добавьте:

return JsonConvert.SerializeObject(person);

для функции GetJson в соответствии с ответом Юунаса.

    return new HttpResponseMessage(HttpStatusCode.OK)
       {
           Content = new StringContent(GetJson(), Encoding.UTF8, "application/json")
       };