通过命令行传递JSON字符串

时间:2015-03-09 10:40:56

标签: c# json cmd

我将一个对象序列化为json字符串并通过命令行将其传递给应用程序但是当我在应用程序中收到参数时,这不再是json字符串而是常规字符串。

我正在使用下面的代码来创建json字符串

var jsonStr = new JavaScriptSerializer().Serialize(obj);

我传递的字符串 - “{”name“:”abc“,”place“:”xyz“}”

我收到的字符串 - “{name:abc,place:xyz}”;

如何维护json字符串的结构?

3 个答案:

答案 0 :(得分:10)

我认为双重报价已经消失,因为它们在CLI世界中具有意义。

我会说将整个JSON转换为基本64字符串,然后在CLI内部再次转换为常规字符串应该可以工作:

var jsonStr = Convert.ToBase64String(Encoding.UTF8.GetBytes(new JavaScriptSerializer().Serialize(obj)));

// When your receive the whole string....
var jsonStr = Encoding.UTF8.GetString(Convert.FromBase64String(inputStr));

// Now deserialize your JSON string into a regular .NET object...

回答@Panagiotis Kanavos的一些评论...

  

CLI不会破坏任何字符串 - 人们现在已经注意到了。   如果OP发送不同的字符串,则问题出在该代码中,而不是   CLI

正如我在评论中指出的那样,我知道在.NET世界中我们不需要逃避JSON,也许在其他环境中也没有必要这样做。

我建议使用base 64方法,因为它是一个防弹解决方案,并且因为OP提供的细节和代码示例不足,所以在一天结束时,我相信它的基本64方法与仅仅避免双重报告一样有效,但它也提供了附加价值:除了"之外,它还会逃避任何特殊字符。

顺便说一句,实际情况是CLI会阻止某些字符。 Windows上的redis-cli不允许使用大括号...

更新2

由于@Panagiotis Kanavos将CLI与公共语言接口混为一谈,我想确保每个阅读我的答案的人都将CLI理解为命令行界面

答案 1 :(得分:6)

只需使用反斜杠转义引号,这样CMD就不会删除JSON中的引号。

应该传递的字符串:

"{\"name\":\"abc\",\"place\":\"xyz\"}"

将收到的字符串:

{"name":"abc","place":"xyz"}

使用此代码转义字符串:

string jsonString = new JavaScriptSerializer().Serialize(obj);
string escapedString = jsonString.Replace("\"", "\\\"");

答案 2 :(得分:0)

首先,JavaScriptSerializer.Serialize不会返回您发布的字符串,它会返回正确引用的字符串:

class Item
{
    public string name { get; set; }
    public string place { get; set; }
}
....
var t = new Item {name = "abc", place = "xyz"};
var s = JsonConvert.SerializeObject(t);
Debug.Assert(s == "{\"name\":\"abc\",\"place\":\"xyz\"}");

这实际上是关于CMD及其如何使用引号的问题。

问题是命令行使用"作为分隔符,因此您必须在字符串中转义引号,就像使用.NET一样。

幸运的是,反斜杠也是CMD中的转义字符,因此myprog.exe "{\"name\":\"abc\",\"place\":\"xyz\"}"将保留引号,以下内容将起作用

var newItem = new JavaScriptSerializer().Deserialize<Item>(args[0]);

快速而肮脏的逃避引号的方法是将其替换为\"

var encoded=s.Replace("\"", "\\\"");

注意多个反斜杠 - 反斜杠和引号都需要转义。

<强>更新

可以通过使用管道或将json字符串保存到单独的文件来避免完全转义来混淆json字符串。在这两种情况下,能够编辑脚本而不必编码/解码命令和数据对于人类来说非常重要。例如。管理员应该能够快速更正或检查参数,而无需编码/解码简单的json字符串。

在两种情况下,在使用脚本时在命令行中使用json字符串是有意义的:

  1. 第一个程序创建一个必须由第二个程序处理的Json输出
  2. 第一个程序生成一个调用第二个程序的批处理文件,传递一个json参数。
  3. 在第一个场景中,如果第一个程序只是写入控制台并且第二个程序从控制台读取而不是检查它,则可以将第一个程序的输出传送到第二个程序的输入。参数。在这种情况下不需要转义,因为字符串按原样从第一个程序传递到第二个程序。

    这具有额外的优点,即json字符串可以写入中间文件,例如。用于检查或允许以后运行第二个程序。

    在第二个场景中,第一个程序创建文件,并使用管道将其传递给第二个程序,或者将文件的路径作为参数传递。

    第二个程序允许管道化所需的唯一更改是使用Console.ReadToEnd()从控制台而不是args数组中读取。

    例如,第一个程序应以:

    结束
    var s = JsonConvert.SerializeObject(t);
    Console.WriteLine(s);
    

    并且第二个程序应该从控制台读取输入:

    var json=Console.ReadToEnd();
    var newItem= new JavaScriptSerializer().Deserialize<Item>(t);
    

    这将允许您创建一个简单的脚本:

    first.exe | second.exe
    

    myJson.json > second.exe