使用 JUST for C#,是否可以规范化双序列化?

Using JUST for C#, is it possible to normalize double-serialization?

我们有一个微服务,它从 Salesforce 接收事件,然后将它们发布到 Azure 服务总线。

Salesforce 事件通常不能包含子记录或列表。 作为 hack,我们正在序列化这些数据并将其塞入长文本。

我们的微服务能够获取 Salesforce 输入并在将结果转发到 Azure 服务总线之前将 JUST 模板应用于输入。 JUST 代表“JSON Under Simple Transformation”,这是一个转换 JSON 的库,类似于 XSL 如何转换 XML.

所以,我们可能会收到一个 JSON,看起来像:

{
  "data": {
    "schema": "zowqvqZB821tITs2yGoDPQ",
    "payload": {
      "Account__c": "{\"BillingCity__c\":\"Frankfurt0.7402008498784405\",\"BillingCountry__c\":\"Germany0.034598927398245216\"}",
      "OpportunityLineItems__c": "[{\"SystemName__c\":\"SF\",\"Currency__c\":\"EUR\"},{\"SystemName__c\":\"SF\",\"Currency__c\":\"USD\"}]"
    },
    "event": {
      "replayId": 5507836
    }
  },
  "channel": "/event/Contract__e"
}

我们想规范化这个双序列化数据,将包含 JSON 的字符串转换为未包装的对象或数组。所以,它应该像这样结束:

{
  "data": {
    "schema": "zowqvqZB821tITs2yGoDPQ",
    "payload": {
      "Account__c": {
          "BillingCity__c": "Frankfurt0.7402008498784405",
          "BillingCountry__c": "Germany0.034598927398245216"
      },
      "OpportunityLineItems__c": [
       {
          "SystemName__c": "SF",
          "Currency__c": "EUR"
       }, 
       {
          "SystemName__c": "SF",
          "Currency__c": "USD"
       }]
    },
    "event": {
      "replayId": 5507836
    }
  },
  "channel": "/event/Contract__e"
}

我尝试创建以下自定义函数:

using LanguageExt;
using Newtonsoft.Json.Linq;
using System;

namespace Salesforce.EventListener.Just.CustomFunctions;

public class NormalizeSerialization
{
    public static Either<JToken, string> TryUnquote(string quotedJson)
    {
        try
        {
            return JToken.Parse(quotedJson);
        }
        catch (Exception)
        {
            return quotedJson;
        }
    }
}

然后在 JUST 模板中包含对此的调用,例如:

{
    "account": "#customfunction(Salesforce.EventListener.Just.CustomFunctions,Salesforce.EventListener.Just.CustomFunctions.NormalizeSerialization.TryUnquote,#valueof($.payloadProperties.Account__c))"
}

但这会导致

System.Exception: 'Error while calling function : #customfunction(Enpal.Salesforce.EventListener.Just.CustomFunctions,Enpal.Salesforce.EventListener.Just.CustomFunctions.NormalizeSerialization.TryUnquote,#valueof($.payloadProperties.Account__c))

  • Value cannot be null. (Parameter 'type')'

在静态函数中放置断点没有帮助,因为系统似乎无法从函数内部中断。

我怎样才能使这个工作?

我将规范器修改为如下所示:

public class Normalizer
{
    public static object TryUnquote(object value)
    {
        try
        {
            return value is string quotedValue
                ? JToken.Parse(quotedValue)
                : value;
        }
        catch (Exception)
        {
            return value;
        }
    }
}

然后像这样在 JsonTransformer 上注册它:

    public static IServiceCollection AddJustCustomFunctions(this IServiceCollection services)
    {
        _ = Assembly.GetAssembly(typeof(Normalizer));

        JUSTContext context = new();
        context.RegisterCustomFunction("Enpal.JUST.CustomFunctions", "CustomFunctions.Normalizer", "TryUnquote", "tryunquote");

        return services.AddSingleton(new JsonTransformer(context));
    }