如何在json单引号中写入c#字符串

Posted

技术标签:

【中文标题】如何在json单引号中写入c#字符串【英文标题】:How to write c# string in json single quotes 【发布时间】:2018-06-06 06:35:00 【问题描述】:

我正在用 json-rpc 编写一个程序,我想在 json 字符串中声明字符串变量,我在声明它时犯了错误,不知道什么是正确的格式,有没有人可以解决这个问题。

(string amnt= "1000000"我想用单引号声明成json量)

string amnt = "100000000";
        string json = @"
        
'method': 'submit',
'params': [
    'secret': 'snL7AcZbKsHm1H7VjeZg7gNS55Xkd',
    'tx_json': 
        'Account': 'rHSqhmuevNJg9ZYpspYHNnQDxraozuCk5p',
        'TransactionType': 'PaymentChannelCreate',
        'Amount': '"+amnt+"',
        'Destination': 'rD6CGd2uL9DZUVDNghMqAfr8doTzKbEtGA',
        'SettleDelay': 86400,
        'PublicKey': '023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6',
        'DestinationTag': 20170428
    ,
    'fee_mult_max': 1000
]

        ";

【问题讨论】:

'Amount': '"+amnt+"',此字段给出错误它的格式不正确,它应该是'Amount': '100000', 将Json映射到对象,然后在对象声明中添加属性,初始化值,并将其序列化回json @$"'Amount': 'amnt'" 之类的呢? 'Amount' : '100000000' 我需要这个,如果我这样做它运行成功,但我想删除 6 个零,然后剩下 100 个,它应该是动态的。 解决方案将在外部声明一个字符串,但将字符串变量放在字符串 json 中会出错 【参考方案1】:

立即的问题是你有两个字符串文字:一个逐字字符串文字在开头,然后是一个常规字符串文字 在字符串与amnt 连接之后。为了使其更易于查看,您需要:

string text = @"some text
                more text" + amnt + "more text
                more text";

第二个字符串文字是常规字符串文字,这意味着它不能超过多行。这就是您目前遇到错误的原因。

这不是您遇到的唯一问题:

此时您生成的 JSON 无论如何都是无效的,因为所有这些单引号都应该是双引号。虽然一些 JSON 解析器允许使用单引号,但这确实违反了 RFC 7159 将所有内容都放在字符串文字中是一种非常脆弱的生成 JSON 的方式。很容易出现小错字并导致 JSON 无效。

这里有几个选项:

您可以使用逐字插值 字符串文字,允许您使用amnt 编写单个文字以在其中包含值。缺点是您需要将所有大括号加倍以表明您想要实际的大括号 您可以通过在其开头添加 @ 将第二个字符串文字设为逐字字符串文字 您可以避免在字符串中执行所有这些操作,并使用 JSON 库来生成 JSON。

我会肯定选择最后一个选项 - 我会使用 Json.NET。

在 Json.NET 中有很多方法可以做到这一点。例如:

您可以在常规类中为 JSON 对象建模,并序列化这些类的实例。如果您不止一次需要这个 JSON,我会这样做。这将允许您使用惯用的 C# 名称来表示属性,使用属性来指定这些属性应如何在 JSON 中表示。 您可以使用 LINQ to JSON 创建 JObjectJArray 实例。 您可以使用匿名类型。

这是后一种方法的示例:

using System;
using Newtonsoft.Json;

class Test

    public static void Main()
    
        string amount = "1000000";
        var obj = new
        
            method = "submit",
            // Note: @ is required as params is a keyword
            @params = new[]
            
                new
                
                    secret = "snL7AcZbKsHm1H7VjeZg7gNS55Xkd",
                    tx_json = new
                    
                        Account = "rHSqhmuevNJg9ZYpspYHNnQDxraozuCk5p",
                        TransactionType = "PaymentChannelCreate",
                        Amount = amount,
                        Destination = "rD6CGd2uL9DZUVDNghMqAfr8doTzKbEtGA",
                        SettleDelay = 86400,
                        PublicKey = "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
                        DestinationTag = 20170428
                    ,
                    fee_mult_max = 1000
                
            
        ;
        string json = JsonConvert.SerializeObject(obj, Formatting.Indented);
        Console.WriteLine(json);
    

输出:


  "method": "submit",
  "params": [
    
      "secret": "snL7AcZbKsHm1H7VjeZg7gNS55Xkd",
      "tx_json": 
        "Account": "rHSqhmuevNJg9ZYpspYHNnQDxraozuCk5p",
        "TransactionType": "PaymentChannelCreate",
        "Amount": "1000000",
        "Destination": "rD6CGd2uL9DZUVDNghMqAfr8doTzKbEtGA",
        "SettleDelay": 86400,
        "PublicKey": "023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6",
        "DestinationTag": 20170428
      ,
      "fee_mult_max": 1000
    
  ]

【讨论】:

好的...黛西我只是在尝试用您当前的方法替换您的方法...请给我时间...【参考方案2】:

你需要在amnt+之后一次在开头放两次@符号

string amnt = "100000000";
      string json = @"
    
       'method': 'submit',
      'params': [
       'secret': 'snL7AcZbKsHm1H7VjeZg7gNS55Xkd',
        'tx_json': 
    'Account': 'rHSqhmuevNJg9ZYpspYHNnQDxraozuCk5p',
    'TransactionType': 'PaymentChannelCreate',
    'Amount': '"+amnt+@"', //change here
    'Destination': 'rD6CGd2uL9DZUVDNghMqAfr8doTzKbEtGA',
    'SettleDelay': 86400,
    'PublicKey': '023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6',
    'DestinationTag': 20170428
     ,
'fee_mult_max': 1000
      ]

    ";

这里提到https://***.com/a/556142/1322204 @ 将字符串标记为逐字字符串文字 - 字符串中通常被解释为转义序列的任何内容都将被忽略。因此在 amnt+ 之后添加额外的 @ 表示这是一个多行字符串。

【讨论】:

请注意,您实际上并没有解释为什么 OP 需要这样做 - 他们仍然留下无效的 JSON 和非常脆弱的代码。我会强烈建议为此使用 JSON 库而不是脆弱的字符串文字。 dude,你能告诉我,如果我想在这个 json 中提到不带单引号的目标标签并声明另一个字符串,那么该怎么办? @Jitender 没找到你 'DestinationTag': 20170428 不是单引号,它就像这个 json 中的整数值,我想动态地给出这个 20170428,因为我必须在外部的字符串变量中声明它,就像你解决了我的以前的问题,但这不是单引号 ok 'DestinationTag':"+ intDestTag+@",单引号无所谓【参考方案3】:

迄今为止最好的答案来自 Sujit.Warrier

但是旧的替换也很好用

    string amnt = "100000000";
                string json = @"
           
    'method': 'submit',
    'params': [
        'secret': 'snL7AcZbKsHm1H7VjeZg7gNS55Xkd',
        'tx_json': 
            'Account': 'rHSqhmuevNJg9ZYpspYHNnQDxraozuCk5p',
            'TransactionType': 'PaymentChannelCreate',
            'Amount': 'amnt',
                'Destination': 'rD6CGd2uL9DZUVDNghMqAfr8doTzKbEtGA',
                'SettleDelay': 86400,
                'PublicKey': '023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6',
                'DestinationTag': 20170428
            ,
            'fee_mult_max': 1000
        ]

    ";

MessageBox.Show( json.Replace("amnt", amnt));

【讨论】:

我不认为使用字符串文字是最好的答案。这个答案和 Sujit.Warrier 仍然留下了一个脆弱的、容易弄乱的字符串文字,它给出了无效的 JSON。没有必要 - 有很多替代方法可以以更易读和可维护的方式创建有效的 JSON。 最好是主观的。取决于需要仍然可以使用字符串文字。 存在一些主观性,但事实上 a) 这仍然会产生无效的 JSON 和 b) 任何更改都需要非常小心以确保结构仍然有效(确保打开和关闭大括号进入正确的地方等)向我暗示这不是一个好主意。如果您要争辩它是主观的,那么我会说在您的答案开始时说明它没有什么意义(特别是以一种 suggests 这是客观的而不是意见的方式) . 它基于给定的问题。他要求单引号并希望将其放在单引号中。所以根据他的需要,这是他需要的最佳答案请参考问题'我想在单引号中以 json 数量声明它' 确实,它回答了这个问题 - 但让 OP 留下无效的 JSON,根本没有说明这一点。这就像提供一个对 SQL 语句中的值使用字符串连接而不是推荐参数化 SQL 的答案。我将其视为“注意义务”,以突出 OP 代码的其他重大问题......并且我认为产生有效 JSON 的答案比产生无效 JSON 的答案更好,除非 OP 表明他们'请注意 JSON 无效,他们有一些特殊原因想要无效 JSON。【参考方案4】:

我想你想做这样的事情:

string amnt = "100000000";
string json = $@"

    'method': 'submit',
    'params': [
        'secret': 'snL7AcZbKsHm1H7VjeZg7gNS55Xkd',
        'tx_json': 
            'Account': 'rHSqhmuevNJg9ZYpspYHNnQDxraozuCk5p',
            'TransactionType': 'PaymentChannelCreate',
            'Amount': 'amnt',
            'Destination': 'rD6CGd2uL9DZUVDNghMqAfr8doTzKbEtGA',
            'SettleDelay': 86400,
            'PublicKey': '023693F15967AE357D0327974AD46FE3C127113B1110D6044FD41E723689F81CC6',
            'DestinationTag': 20170428
        ,
        'fee_mult_max': 1000
    ]
";

$ 符号 用于插入字符串,您可以在此处阅读更多内容:

https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/tokens/interpolated

另外,如果您有可以考虑使用 JSON.NET 的对象

https://bridge.net/jsonnet

【讨论】:

first 可能与字符串插值冲突 所有除了用于插值的大括号外,都需要加倍。虽然可以做到,但我绝对不会推荐它。

以上是关于如何在json单引号中写入c#字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的序列化 JSON 字符串包装在“单引号”中

如何将带单引号的字符串转换为双引号以进行 json 解析

当字符串在双引号内有单引号时,如何在Javascript中将此字符串转换为JSON对象

如何将单引号 (') 捕获到 JSON.parse 的字符串中?

如何在 JavaScript 函数中使用单引号(撇号)转义 JSON 值

用 C# 替换完整 sql 查询中的单引号