First, JavaScriptSerializer.Serialize doesn't return the string you posted, it returns a properly quoted string:
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\"}");
This is really a question about CMD and how it uses quotes.
The problem is that the command line uses "
as a delimiter so you have to escape quotes in your strings, just as you would do with .NET.
Luckily, the backslash is the escape character in CMD as well, so myprog.exe "{\"name\":\"abc\",\"place\":\"xyz\"}"
will preserve the quotes, and the following will work
var newItem = new JavaScriptSerializer().Deserialize<Item>(args[0]);
A quick and dirty way to escape quotes is to replace them with \"
:
var encoded=s.Replace("\"", "\\\"");
Notice the multiple backslashes - both the backslash and the quote need to be escaped.
UPDATE
It's possible to avoid escaping entirely and obfuscating the json string either by using piping or by saving the json string to a separate file. In both cases, it's important for humans to be able to edit the script without having to encode/decode the commands and data. Eg. an administrator should be able to make quick corrections or inspect the parameters without having to encode/decode a simple json string.
Using a json string in a command line makes sense when using scripts, in two scenarios:
- The first program creates a Json output that must be processed by the second program
- The first program generates a batch file calling the second program, passing a json parameter.
In the first scenario, the first program's output can be piped to the second program's input if the fist program simply writes to the console and the second program reads from the console, instead of inspecting its parameters. No escaping is needed in this case because the string is passed as-is from the first program to the second.
This has the additional advantage that the json string can be written to an intermediate file eg. for inspection or to allow running the second program at a later time.
In the second scenario the first program creates the file and either uses piping to pass it to the second program, or passes the file's path as a parameter.
The only change needed by the second program to allow piping is to use Console.ReadToEnd()
to read from the console instead of the args
array.
For example, the first program should end with:
var s = JsonConvert.SerializeObject(t);
Console.WriteLine(s);
and the second program should read the input from the console:
var json=Console.ReadToEnd();
var newItem= new JavaScriptSerializer().Deserialize<Item>(t);
This will allow you to create a script as simple as:
first.exe | second.exe
Or
myJson.json > second.exe