C#字符串插值-转义双引号和花括号

C# string interpolation-escaping double quotes and curly braces

伙计们,

我正在从一个内插字符串构建一个 JSON 对象,但不知道转义是如何工作的。我必须为 API 使用双引号。

这不会插入花括号之间的表达式:

@"{{
                        ""name"":""{taskName}"", 
                        ""products"": [    
                                    {""product"": ""ndvi_image"", ""actions"": [""mapbox"", ""processed""]}, 
                                    {""product"": ""true_color"", ""actions"": [""mapbox"", ""processed""]}
                                  ], 
                        ""recurring"":true,
                        ""query"":    {
                                        ""date_from"": ""{dateFromString}"",
                                        ""date_to"": ""{dateToString}"",
                                        ""aoi"": {polygon}
                                    },
                        ""aoi_coverage_percentage"":90
                        }}";

这会抛出一堆错误——显然,大括号没有被正确转义:

$"{{
                        ""name"":""{taskName}"", 
                        ""products"": [    
                                    {""product"": ""ndvi_image"", ""actions"": [""mapbox"", ""processed""]}, 
                                    {""product"": ""true_color"", ""actions"": [""mapbox"", ""processed""]}
                                  ], 
                        ""recurring"":true,
                        ""query"":    {
                                        ""date_from"": ""{dateFromString}"",
                                        ""date_to"": ""{dateToString}"",
                                        ""aoi"": {polygon}
                                    },
                        ""aoi_coverage_percentage"":90
                        }}";

我应该如何格式化它以保留内部双引号和外括号,同时允许插入单括号内的值?

除了 @"..."$"..." 之外,C# 还支持 $@"..." 字符串,这正是您在构建需要插值的多行字符串文字时所需要的:

$@"{{
    ""name"":""{taskName}"", 
    ""products"": [    
                {{""product"": ""ndvi_image"", ""actions"": [""mapbox"", ""processed""]}}, 
                {{""product"": ""true_color"", ""actions"": [""mapbox"", ""processed""]}}
              ], 
    ""recurring"":true,
    ""query"":   {{
                    ""date_from"": ""{dateFromString}"",
                    ""date_to"": ""{dateToString}"",
                    ""aoi"": {polygon}
                }},
    ""aoi_coverage_percentage"":90
}}";

您似乎错过了 productsquery 对象的转义:

$@"{{
    ""name"":""{taskName}"",
    ""products"": [
        {{""product"": ""ndvi_image"", ""actions"": [""mapbox"", ""processed""]}},
        {{""product"": ""true_color"", ""actions"": [""mapbox"", ""processed""]}}
    ],
    ""recurring"":true,
    ""query"": {{
        ""date_from"": ""{dateFromString}"",
        ""date_to"": ""{dateToString}"",
        ""aoi"": {polygon}
    }},
    ""aoi_coverage_percentage"":90
}}";

以防万一其他人正在考虑做同样的事情,最好创建一个匿名类型并将其序列化为 json,原因有两个:

  1. 它更具可读性和可维护性(由于 json 结构已更改,同时保持所有转义顺序 - 尤其是在没有单元测试的情况下,更改代码需要多长时间?)
  2. 它更可靠(如果 taskName 有双引号怎么办?)

下面使用json.net进行序列化。

var jsonObj = new {
  name = taskName,
  products = new[] {
    new { product = "ndvi_image", actions = new [] { new { mapbox = "processed" } },
    new { product = "true_color", actions = new [] { new { mapbox = "processed" } }
  },
  recurring = true,
  query = new {
    date_from = dateFromString,
    date_to = dateToString,
    aoi = polygon
  },
  aoi_coverage_percentage = 90
};

var jsonString = JsonConvert.SerializeObject(jsonObj);