I need to POST a JSON string to a page.
The page is external and out of my control, and it expects the post data to be in the web-form post format (key1=value1&key2=value2)
How can I convert the JSON string to this format?
This can be done by first deserializing your JSON to a Dictionary<string, string>, then iterating through the key-value pairs in the dictionary and building up a querystring from that.
However, keep in mind that querystring format (application/x-www-form-urlencoded) is not a hierarchical format, while JSON is. So your JSON object can only be a simple object with key-value pairs (no arrays or nested objects). If your JSON is more complicated than that, you will have to do some more work to flatten it before you can convert it to a querystring.
Demo:
class Program
{
static void Main(string[] args)
{
string json = #"
{
""key1"" : ""value1"",
""key2"" : ""value2"",
""int"" : 5,
""bool"" : true,
""decimal"" : 3.14,
""punct"" : ""x+y=z""
}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(json);
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string, string> kvp in dict)
{
if (!string.IsNullOrEmpty(kvp.Key) && !string.IsNullOrEmpty(kvp.Value))
{
if (sb.Length > 0) sb.Append('&');
sb.Append(HttpUtility.UrlEncode(kvp.Key));
sb.Append('=');
sb.Append(HttpUtility.UrlEncode(kvp.Value));
}
}
var postDataString = sb.ToString();
Console.WriteLine(postDataString);
}
}
Output:
key1=value1&key2=value2&int=5&bool=True&decimal=3.14&punct=x%2by%3dz
As was mentioned in the comments, you can use the FormUrlEncodedContent class to do the same thing. Replace the StringBuilder and foreach loop in the code above with the following (but note this approach requires async/await):
var formUrlEncodedContent = new FormUrlEncodedContent(dict);
var postDataString = await formUrlEncodedContent.ReadAsStringAsync();
You don't post JSON like that. You set the Content-Type header to "application/json" and then you simply fill the content body with the JSON as-is.
There is no built in support in C# or JSON.NET to serialize JSON into form post data, but you can probably use LINQ to JSON to write a translater yourself relatively easy, assuming the JSON format is simple enough.
Is the Json being passed in always the same? Your best bet is to deserialize the Json to a C# class then create your post data from that.
Related
I'm working with this Json structure, but I don't know how to get the values of the part of the "json" key
I'm using this code to send a request to an API, and the return is an Json object:
var reqData = (HttpWebRequest)WebRequest.Create(string.Format("http://server_ip/system/message/date/{0}/", txtDate.Text));
reqData.ContentType = "application/json";
reqData.Method = "GET";
var answer = (HttpWebResponse)reqData.GetResponse();
List<Dictionary<string, string>> convert = JsonConvert.DeserializeObject<List<Dictionary<string, string>>>(answer);
The result is a Json structure like this:
"[
{
\"idMessage\":\"--Message Id--",
\"idTemplate\":--TemplateId--,
\"mail\":\"--mail dir--\",
\"subject\":\"--message subject--\",
\"json\":\"{
\\\"Id\\\":\\\"--Person Id--\\\",
\\\"name\\\":\\\"--Person name--\\\",
\\\"date\\":\\\"--Register date-\\\",
\\\"hour\\\":\\\"--Register hour--\\\"
}\",
\"senddate\":\"--sent date--\",
\"status\":0,
\"template\":null
}
]"
I want to get the values (Id,name,date,hour) from the json part of this Json string, can someone help me to get this values?
That json property contains a string of more JSON, so you have to deserialize that again, the same way you did the whole outer structure.
So now that you have your convert array, you can pull out the first object, grab the value of json and deserialize that:
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(convert[0]["json"]);
Then you can pull each value out like this:
var id = json["Id"];
Mind you, the JSON in your question isn't actually valid. There are a few errors in it. But I'm assuming that they're just copy/paste errors and the web service is actually returning valid JSON.
Is there a function where you can select multiples "nodes" on JSON string?
Sample:
var myJson = #"{
'channel' : 'nine',
'segment' : 'mobile',
'food' : 'pizza'
}";
var myObjectFromJson = JObject.Parse(myJson);
var channelFoodNodes = myObjectFromJson.SelectTokens("channel, food"); //<- This call not works!
Expected result:
{
"channel" : "nine",
"food" : "pizza"
}
Reference:
Querying JSON with SelectToken
First, your code is invalid with the newlines (your string should be a verbatim string if you want to put newlines in it without concatenating, with # in front of it, and quotes replaced by double quotes).
Second, you are trying to invoke SelectTokens() on a string... you need to parse it to a JObject first:
var myJson = JObject.Parse(#"
{
""channel"" : ""nine"",
""segment"" : ""mobile"",
""food"" : ""pizza""
}");
Then myJson is a JObject (and not a string) where you can call SelectTokens() on
HOWEVER, what you want to achieve can't be achieved with JPath (which is what SelectTokens() uses), so you'd be better off parsing the object directly, something like:
var channelFoodNodes = myJson.Children()
.OfType<JProperty>()
.Where(x => new []{ "channel", "food"}.Contains(x.Name));
Then you can construct a new JObject from the resulting enumerable of JProperties:
var newObject = new JObject(channelFoodNodes);
Which will contain your resulting object.
You can see it all in action in this fiddle
If you want to select the properies this way (as you were trying to do with SelectTokens()), you can also build a simple extension method:
public static IEnumerable<JProperty> SelectRootProperties(this JObject obj, params string[] propertyNames)
{
return obj.Children().OfType<JProperty>().Where(x => propertyNames.Contains(x.Name));
}
And call it like:
myObject.SelectRootProperties("channel", "food");
See it in action in this other fiddle
(or you could also make a simple method which gets the input json string and the property names, construct the JObject, parse the properties and return the string of the resulting object, which seems to be what you are asking, but I'll leave that as an exercise)
Your existing data is a key/value of strings. You can deserialize it to a Dictionary<string, string> and access the pieces you want from the dictionary produced.
var things = JsonConvert.DeserializeObject<Dictionary<string,string>>(json);
Console.WriteLine(things["channel"]);
Console.WriteLine(things["food"]);
I am sending a request to a WebAPI using following code:
client.PostAsync(baseAddress + path, new FormUrlEncodedContent(JsonConvert.DeserializeObject<Dictionary<string,string>>(form)))
where client is an object of HttpClient class. This code is executed for all the requests to the WebApi. I am trying to send following data to the API:
{
"code":"GUEST",
"category":"Indian",
"sections":["01000000-0000-0000-0000-000000000000","02000000-0000-0000-0000-000000000000"],
"date":"0001-01-01T00:00:00",
"time":"0001-01-01T00:00:00",
"quantity":1.0,
"price":0.0,
"discount":0.0,
"paymentMethod":"ID",
"paymentMethodID":null,
"ticketNo":null
}
Now because the FormUrlEncodedContent accepts only the Dictionary<string,string> object, I am converting this JSON into that type using NewtonSoft's JSON.NET method JsonConvert.DeserializeObject. But at the point where sections array starts, it is showing me this error message:
Unexpected character encountered while parsing value:[. Path 'sections'.
So, what approach should I follow if I want to use the same code for this kind of JSON data?
If you for any reason need to send all values as strings, then you must convert array of strings to string before deserializing it to Dictionary<string, string>.
It can be done like this:
var json = "{\"code\":\"GUEST\",\"category\":\"Indian\",\"sections\":[\"01000000-0000-0000-0000-000000000000\",\"02000000-0000-0000-0000-000000000000\"],\"date\":\"0001-01-01T00:00:00\",\"time\":\"0001-01-01T00:00:00\",\"quantity\":1.0,\"price\":0.0,\"discount\":0.0,\"paymentMethod\":\"ID\",\"paymentMethodID\":null,\"ticketNo\":null}";
var jObject = JObject.Parse(json);
jObject["sections"] = JsonConvert.SerializeObject(jObject["sections"].ToObject<string[]>());
var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(jObject.ToString());
That way you will get result:
I'm deserializing (or parsing) a json string to a c# object (using Json.NET) and getting a JObject. I want to iterate all the properties with the key "bla", in the same way iterating all xml elements that named "bla" with XElement.Elements("bla").
If it's not possible, I would like to deserialize my json string into a c# object, and work dynamically and recursively on my deserialized json object (my json string can have lists / arrays that can have objects of 2 types.
In the end after editing my object (changing values and removing or adding properties) I need to serialize my object back to a json string.
Which is the best and easiest way to use json serializing and deserializing?
my Json looks like this:
{"Families":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}, {"propA":"dhsj", "propB":"fghfgh"}]}]}
in conclusion, the json value is a json object that it's value is a list/array, the list/array can contain 2 "types" of objects, and one of these types also has a property which it's value is a json object that it's value is a list/array, and it goes like this recursively. sometimes the value of one of the props of the type that doesn't have a property which it's value is a json object that it's value is a list/array, can be a list/array itself, that can contain only 1 type of the two mentioned.
If you don't need a strongly-typed object, you can deserialize to a dictionary:
Dictionary<string, object> myObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jsonString);
And then just use it as a dictionary:
myObject["Property"] = value;
Or
foreach(var propertyKey in myObject.Keys)
{
// do something with each property
Console.WriteLine($"{propertyKey} = {myObject[propertyKey]}");
}
Here's a fiddle
You can serialize it back after you are done
My json looks more like this:
{"Familys":{"Family":[{"propA":"dhsj", "propB":"dhdisb"}, {"propA":"krbsbs", "propC":"ksndbd", "propD":"odndns", "Families":{"Family":[....]}}]}
For JSON like this:
var json = #"{
""Families"":{
""Family"":[
{
""propA"":""Top""
},
{
""propA"":""Top.Lower"",
""Families"":{
""Family"":[
{
""propB"":""propB value""
},
{
""propA"":""Top.Lower.EvenLower"",
""Families"":{
""Family"":[
{
""propA"":""Top.Lower.EvenLower.EvenLower""
}
]
}
}
]
}
}
]
}
}";
Do something like this:
//calling code makes use of "dynamic" to make things clean and readable.
dynamic parsedJson = JsonConvert.DeserializeObject(json);
var allPropAValues = GetPropAValues(parsedJson);
//**** NOTE: this has our extra property ****
var jsonWithExtraStuffProperty = JsonConvert.SerializeObject(parsedJson);
//recursive function that reads AND writes properties
public static List<string> GetPropAValues(dynamic obj)
{
var propAValues = new List<string>();
//**** NOTE: the use of an added property ****
obj.ExtraStuff = new Random().Next();
//if we have a propA value, get it.
if (obj.propA != null)
propAValues.Add(obj.propA.Value);
//iterate through families if there are any. your JSON had Families.Family.
if (obj.Families != null)
foreach (dynamic family in obj.Families.Family)
propAValues.AddRange(GetPropAValues(family));
return propAValues;
}
I'm using "Newtonsoft.Json.Linq.JObject" in my application.
I have a method that receives a JObject in the format:
{
"PersonnelIds": "[31,32,33,34]"
}
And I want to parse the content of PersonnelIds to a List of Integers.
What is the best way of doing that?
I can see that the values of the PersonnelIds is written as string "[31,32,33,34]" so to parse it with this syntax you can use the following code
JObject jObject = JObject.Parse(myjson);
JToken jToken = jObject.GetValue("PersonnelIds");
var array = JArray.Parse(jToken.Value<string>()).Select(x => (int)x).ToArray();
if your value is not string so your JSON is like {"PersonnelIds": [31,32,33,34]
} then you can parse it using the following code
JObject jObject = JObject.Parse(myjson);
JToken jToken = jObject.GetValue("PersonnelIds");
int[] array = jToken.Values<int>().ToArray();
Create a class to deserialize your json:
To create classes, you can copy the json in clipboard and use the
Edit / Paste special / Paste JSON as class
in visual studio (I use vs2013).
Then deserialize your string.
See my solution on this post