将 Json 转换为 Poco 集合/如何为每个对象编写代码?

Convert Json to Poco Collection/ How to code a For Each?

我对 Azure Functions 还很陌生。

我创建了一个 C# WebHook/Azure 函数(我想这是正确的)来获取我的 json 内容并将其转换为简单的 poco/dto 对象的集合。

public static class GenericWebHookCSharp
{
    [FunctionName("GenericWebHookCsharpOne")]
    public static async Task<HttpResponseMessage /* object */> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage req, TraceWriter log)
    {
        try
        {

            log.Info(string.Format("C# GenericWebHookCsharpOne about to process a request. ('{0}')", DateTime.Now.ToLongTimeString()));

            //IUnityContainer container = new UnityContainer();
            //container.RegisterType<IJsonToPersonRequestWrapperConverter, JsonToPersonRequestWrapperConverter>();
            //IJsonToPersonRequestWrapperConverter jsonConvtr = container.Resolve<IJsonToPersonRequestWrapperConverter>();
            //ICollection<Person> emps = await jsonConvtr.ConvertHttpRequestMessageToPersonCollection(req);

            /* above commented code is my "real" code where I  take the INPUT request-body-as-json and convert it into a ICollection of Person(s) */
            /* below code, I just fake-creating some persons */
            string jsonContent = await req.Content.ReadAsStringAsync();
            ICollection<Person> persons = new List<Person>();
            for(int i = 0; i< 10; i++)
            {
                persons.Add(new Person() { PersonUuid = Guid.NewGuid(), LastName = "LN" + i.ToString(), FirstName = "FN" + i.ToString(), BirthDate = DateTimeOffset.Now.AddYears(-1 * (20 + i))});
            }

            string serializedJson = Newtonsoft.Json.JsonConvert.SerializeObject(persons);

            log.Info(string.Format("C# GenericWebHookCsharpOne finished a request. ('{0}')", DateTime.Now.ToLongTimeString()));

            return req.CreateResponse(HttpStatusCode.OK , serializedJson);

        }
        catch (Exception ex)
        {
            string errorMsg = ex.Message;// ExceptionHelper.GenerateFullFlatMessage(ex);
            log.Error(errorMsg);
            return req.CreateResponse(HttpStatusCode.BadRequest, errorMsg);
        }
    }
}

在另一个 .cs 文件中

public class Person
{

    public Guid PersonUuid { get; set; }

    public string LastName { get; set; }

    public string FirstName { get; set; }

    public DateTimeOffset? BirthDate { get; set; }
}

如果我在 Visual Studio 中调试它,它工作正常。

所以我将其添加为我的逻辑应用程序中的一个步骤,如下所示

所以我想添加一个新步骤,即 "for each" 步骤。这是我现在得到的:(下图)。我所看到的只是来自初始触发器的 "body" 和 "convert" webhook 函数(我上面有)......

如何让 "persons"(这样我就可以为每个人做一个)集合显示并可用于逻辑应用程序的下一步?

EDIT/APPEND:

最后的任务是为我的 "each" 个人推送服务总线消息。

应要求,这里是"person json".....

[{
    "PersonUuid": "7ec8cc4d-831c-4c89-8516-47424ee2658d",
    "LastName": "LN0",
    "FirstName": "FN0",
    "BirthDate": "1997-08-17T09:46:16.9839382-04:00"
},
{
    "PersonUuid": "275264bc-5a86-476d-a189-512afa1e3ce4",
    "LastName": "LN1",
    "FirstName": "FN1",
    "BirthDate": "1996-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "e522b827-2d2e-465d-a30a-c4b619d2e8e4",
    "LastName": "LN2",
    "FirstName": "FN2",
    "BirthDate": "1995-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "f16bce36-3491-4519-bc82-580939f61b2e",
    "LastName": "LN3",
    "FirstName": "FN3",
    "BirthDate": "1994-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "42456057-39ef-45aa-bd7c-ad6a8fa74fd1",
    "LastName": "LN4",
    "FirstName": "FN4",
    "BirthDate": "1993-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "14088a6e-3c44-4cb0-927d-19f5eda279c4",
    "LastName": "LN5",
    "FirstName": "FN5",
    "BirthDate": "1992-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "332a5cde-3cd1-467a-9dfc-2b187d6ae32e",
    "LastName": "LN6",
    "FirstName": "FN6",
    "BirthDate": "1991-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "6debe134-19e6-4b16-a91d-05ded511eff6",
    "LastName": "LN7",
    "FirstName": "FN7",
    "BirthDate": "1990-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "e61ef8a1-09d3-4c5b-b948-df8e0858cd29",
    "LastName": "LN8",
    "FirstName": "FN8",
    "BirthDate": "1989-08-17T09:46:16.9844385-04:00"
},
{
    "PersonUuid": "e9b27632-d3a4-4fe8-8745-04edfa8854f7",
    "LastName": "LN9",
    "FirstName": "FN9",
    "BirthDate": "1988-08-17T09:46:16.9844385-04:00"
}]

正如 Steven Van Eycken 提到的,我们可以在逻辑应用程序中使用 json 函数将字符串解析为数组。在您的情况下,我们可以直接从 Azure 函数将字符串解析为逻辑应用程序 or return jarry 中的数组。我们可以选择以下方法之一来做到这一点。我也在自己这边测试过,没问题。

在逻辑应用中

json(body('Your action name'))

Return 直接在 Azure 函数中 Jarry

var jarry =JArray.Parse(Newtonsoft.Json.JsonConvert.SerializeObject(persons));

log.Info(string.Format("C# GenericWebHookCsharpOne finished a request. ('{0}')", DateTime.Now.ToLongTimeString()));

return req.CreateResponse(HttpStatusCode.OK, jarry);

好的。

我得在忘记之前把它写下来。哇,真棒。

首先是 WebHook 上的 C# 代码。请注意 "anonymousPersonWrapper" 代码。

public static class GenericWebHookCSharp
{
    [FunctionName("GenericWebHookCsharpOne")]
    public static async Task<HttpResponseMessage /* object */> Run([HttpTrigger(WebHookType = "genericJson")]HttpRequestMessage req, TraceWriter log)
    {
        try
        {

            log.Info(string.Format("C# GenericWebHookCsharpOne about to process a request. ('{0}')", DateTime.Now.ToLongTimeString()));

            ///////* below code, I just fake-creating some persons */
            string jsonContent = await req.Content.ReadAsStringAsync();
            ICollection<Person> persons = new List<Person>();
            for (int i = 0; i < 3; i++)
            {
                persons.Add(new Person() { PersonUuid = Guid.NewGuid(), LastName = "LN" + i.ToString(), FirstName = "FN" + i.ToString(), BirthDate = DateTimeOffset.Now.AddYears(-1 * (20 + i)) });
            }

            /* the below is the "trick" to allow the for-each to work in the Logic-App.  at least in my experience */
            var anonymousPersonWrapper = new
            {
                personWrapper = persons
            };

            string personWrapperJsonString = JsonConvert.SerializeObject(anonymousPersonWrapper);

            log.Info(string.Format("C# GenericWebHookCsharpOne finished a request. ('{0}')", DateTime.Now.ToLongTimeString()));
            HttpResponseMessage returnReq = req.CreateResponse(HttpStatusCode.OK , personWrapperJsonString );
            return returnReq;

        }
        catch (Exception ex)
        {
            string errorMsg = ex.Message;
            log.Error(errorMsg);
            return req.CreateResponse(HttpStatusCode.BadRequest, errorMsg);
        }
    }
}

但是在 "return returnReq;" 上放置一个断点,我能够看到 personWrapperJsonString 包含以下 Json:

{
    "personWrapper": [{
        "PersonUuid": "31fb318d-a9bf-4c2f-ad16-0810ddd73746",
        "LastName": "LN0",
        "FirstName": "FN0",
        "BirthDate": "1997-08-17T15:10:08.9633612-04:00"
    },
    {
        "PersonUuid": "73fdacc7-e1e8-48ff-b161-1bd8b5f4aec1",
        "LastName": "LN1",
        "FirstName": "FN1",
        "BirthDate": "1996-08-17T15:10:08.9633612-04:00"
    },
    {
        "PersonUuid": "d18b4324-2d3e-41ca-9525-fe769af89e9c",
        "LastName": "LN2",
        "FirstName": "FN2",
        "BirthDate": "1995-08-17T15:10:08.9633612-04:00"
    }]
}

好的。

然后我添加了一个"Parse Json"动作(下图)

然后我设置 Parse-Json。下面.

上面的解析-json设置不完整。

单击按钮 "Use sample payload to generate schema" 将弹出一个新的 window。粘贴之前的 "personWrapper" json。如下图所示。

以上当然会创建您需要的 json-schema(即 for-each friendly)。如下所示。

现在我们很接近了。

添加一个 For-Each(添加新步骤时使用 "More" 按钮)(如下所示)

现在我们设置 for-each。看看出现了什么! "personWrapper"(下图)

笑着说,我将 sessionId 设置为 PersonUuid 值(只是为了表明我可以获得对象的标量属性之一。(下图)。

现在 json 作为服务总线消息的内容。 (下图)

然后我发布了 Azure-Functions 并部署了 Logic-App,并向触发器发送了一个请求。

返回 Azure 门户。 PersonUuid 显示为 SessionId! (下图)

然后在 Service Bus Explorer 中快速检查 "peek" 消息的内容(下图)

好的,一些面包屑:

我从这里得到了关于将收集端放在 "wrapper" 的提示。

Json.NET validate JSON array against Schema

我遇到的一些错误

"Invalid type. Expected Object but got Array."

不支持的媒体类型"The WebHook request must contain an entity body formatted as JSON."

"this output is an array" "a foreach cannot be nested inside of another foreach"

'Json' 期望它的参数是一个字符串或者一个 XML.The 提供的值是 'Array.