Need to parse a JSON coming in via a Post request - c#

I am trying to parse a JSON received in a Post request.
The JSON is as follows. It has to be agnostic as to how many records there are or what the fields are called. But the contact variable is always null when I send it via Postman. Is there something wrong with the class I throw it in to?
{
"Fields":
{
"first":"fn",
"last":"ln",
...
}
}
public class FieldsValues
{
List<KeyValuePair<string, string>> Fields = new List<KeyValuePair<string, string>>() { };
}
public void Post([FromBody]FieldsValues Fields)
{
...
}
I want to send the JSON into a Dictionary object but the value coming in is always null.

Your Json is not an array. You need square brackets to build an array.
Besides this the KeyValuePair has members named "Key" and "Value".
To match the List<KeyValuePair<string, string>> you'll need to input something like this:
{
"Fields":
[{
"Key":"first",
"Value":"fn"
}]
}
If you can't change the JSON structure yourself and the structure is really unknown to you, I would go for a method that accepts raw strings and parse that string with Newtonsoft to a dynamic object.
E.g. this code could accept your JSON:
public void Post()
{
string text = "";
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
text = reader.ReadToEnd();
dynamic dynObj = JObject.Parse(text);
var firstValue = dynObj.Fields.first.Value;
...
}

Related

How to cast a JSON to a string

I have a Post method that receives a fairly simple JSON:
{
"First": "John",
"Last": "Smith"
}
But I need it as a string.
I've tried casting the JSON to a string but it comes up null.
public void Post([FromBody]string jsonData)
{
...
}
I would like to use jsonData as a string. I am trying to avoid creating a class with field names matching the JSON because that would mean changing the API every time a field is added. I just need to receive the JSON as a string at the outset. Is there a way to cast it as such at the endpoint without using variable names?
Just use JToken as parameter.
[HttpPost]
public void PostMethod([FromBody] JToken json)
{
var jsonAsString = json.ToString();
}
Have you try this?
JObject json = JObject.Parse(str);
You might want to refer to Json.NET documentation

Deserialize JSON Data into a List in C#

After hours of searching and trying, can someone please be so kind and help me solving this following simple problem:
I have the following JSON-String:
[
{
"key": 1234,
},
{
"key": 9876,
}
]
How can I read this JSON and write all values into a List?
Had many attempts so far, but please see following code:
List<int> content = new List<int>;
var json = reader.ReadToEnd();
var obj = JObject.Parse(json);
First try:
foreach(var key in obj)
{
content.Add((int)obj["key"]);
}
Other try:
var token = obj.SelectToken("key");
foreach(var item in token)
{
content.Add(JsonConvert.DeserializeObject<int>(item.value));
}
Or something this way?
foreach(var key in obj)
{
content.Add(Int32.Parse(obj.GetValue("key").ToString()));
}
Trying to run the last attempt, I get following error message:
Error reading JObject from JsonReader. Current JsonReader item is not an object: StartArray.
Even if the JSON looks like the following:
[{\"key\":9999},{\"key\":9876}]
Would be very happy for every answer.
Best regards
Use Newtonsoft.Json
It can be done in the following way:
List<string> yourList = JsonConvert.DeserializeObject(YourJson).ToList();
NOTE: It can only be saved as a list of strings , but can be called with: yourList.YourKeyName.
Depends on what you want but you could also create a specified class for your json.
The following class represents your json string.
public class RootObject
{
public int key { get; set; }
}
You could then deserialise your json string as follows:
string json=reader.ReadToEnd();
List<RootObject> myobs=JsonConvert.DeserialiseObject<List<RootObject>>(json);
You can then do stuffs with the list.
foreach(var ob in myobs){
Console.WriteLine(ob.key);
}
Following on to what #bolkay said, you need to define your object:
public class KeyClass
{
public int Key { get; set; }
}
and then if your JSON is in a variable called jsString for example
List<int> content = new List<int>();
var keys = JsonConvert.DeserializeObject<List<KeyClass>>(jsString);
foreach (var item in keys)
{
content.Add(item.Key);
}

Deserialize arbitrary JSON keys and raw values

Using JSON.Net I want to deserialize a JSON object that looks something like this:
"properties": {
"foo": 1,
"bar": "Fred",
"baz": [694481.61, 693638.0, 692624.65, 692354.54]
}
and end up with a dictionary<string,string> that looks like this:
{ "foo", "1" },
{ "bar", "\"Fred\"" },
{ "baz", "[694481.61, 693638.0, 692624.65, 692354.54]" }
The key points to note are:
The keys are not known in advance. (Hence the use of a dictionary rather than deserializing to a class with predefined properties foo, bar and baz.)
The value strings in the dictionary are the raw JSON text from the JSON stream. So strings include their encapsulating quotation marks, and arrays include their encapsulating square brackets.
What I have tried so far
Parse the values as JRaw objects. This would work if I knew the key names in advance: I could declare matching properties in my class as type JRaw - e.g. public JRaw foo { get; set; }. But the key names are not predefined so I can't.
Create a RawValueDictionaryConverter : JsonConverter custom converter that takes the stream and deserializes it directly to a dictionary<string,string>. I thought this would be straightforward, but the raw text of the original stream is not available inside ReadJson(); the stream has already been tokenized and ReadJson() only receives the interpreted token and token type.
Write my own tokenizer and forget about using Json.NET. It may come to this but I don't want to 'reinvent the wheel.'
You can deserialise to Dictionary<string, JRaw> which gets you half way there. For example:
//Example class
public class Root
{
public Dictionary<string, JRaw> properties { get; set; }
}
var json = "<from the question>";
var result = JsonConvert.DeserializeObject<Root>(json);
foreach (var property in result.Properties)
{
var value = property.Value.ToString();
}
If you still want the values as strings, you can convert like this:
var stringDictionary = result.Properties.ToDictionary(p => p.Key, p => p.ToString());

Deserializing string of format "property=whatever&property2=whatever" to an object

I am taking an HttpRequest and reading it to a string
var body = request.Content.ReadAsStringAsync().Result;
This body gives me a string that looks like the following:
"To=Jim&From=Dan+Bailey"
I want to serialize body to aumatically bind to an object that looks like
public class Letter
{
[JsonProperty("To")]
public string To { get; set; }
[JsonProperty("From")]
public string From { get; set; }
}
Any ideas? I tried using JsonSerializer and Newtonsoft.Json.Convert but both require a different format
Json deserializers would only work on Json strings
You may convert the querystring to a NameValueCollection directly using the utility ParseQueryString
var body = request.Content.ReadAsStringAsync().Result;
var parameters = HttpUtility.ParseQueryString(body);
For most purposes, using a NameValueCollection should suffice, but if you still need a strongly-typed object, I would suggest using either reflection, or first serialize to a json string then use Newtonsoft deserializer
var dict = new Dictionary<string, string>();
foreach (var key in parameters.Keys)
{
dict.Add(key, parameters[key]);
}
var json = JsonConvert.SerializeObject(dict);
var obj = JsonConvert.DeserializeObject<Letter>(json);
What you have is not a JSON but most likely a simple html parameter string. Looks like the format is fixed given how your class Letter looks like.
I guess you can just do it with Regex :
var match = Regex.Match("To=Jim&From=Dan+Bailey", "To=(?<To>[^&]+)&From=(?<From>[^&]+)");
var letter = new Letter() { To = match.Groups["To"].Value, From = match.Groups["From"].Value };

Manipulate Values of Stringfied values on C#

I have a below code that used JSON.stringify to the object then passed it on POST method (Please see below Javascript code). I'm getting those values on the backend using C#. My problem is, how could I convert/manipulate/access the stringified values. Please see below C# code
Javascript:
var json_db = JSON.stringify(selectedDbInfo);
$.post("../FormActions/DatabaseChanges.aspx", { action: "savedb", orderNumber: orderNumber, selectedDb: json_db},
function (response) {
alert('ok');
});
C#:
var dbValue = c.Request.Params["selectedDb"];
below is the result value of dbValue
"[{\"dbname\":\"BASINS\",\"distance\":\"0\"},{\"dbname\":\"BROWNFIELD\",\"distance\":\"0.5\"},{\"dbname\":\"BRS\",\"distance\":\"0\"}]"
You need to parse the JSON into a .NET array or List.
Many use json.NET for this: http://james.newtonking.com/json
At a push you could use some string manipulation to populate your objects one by one, but I wouldn't recommend that.
There are many samples here on SO.
if you're just want to convert it dictionary look here:
How can I deserialize JSON to a simple Dictionary<string,string> in ASP.NET?
However, there's a built in mechanism in ASP.NET MVC that serializes automatically your json param to predefined objects at your convenient.
You may define a class having the fields like dbname and distance as properties. Then you may deserialize the json string dbValue into a list of that type using NewtonSoft.Json. Please see the code below:
var list = JsonConvert.DeserializeObject<List<RootObject>>(dbValue);
foreach (var item in list)
{
Console.WriteLine(string.Format("dbname: {0}, distance: {1}", item.dbname, item.distance));
}
Ans the definition of RootObject is as simple as you guess:
public class RootObject
{
public string dbname { get; set; }
public string distance { get; set; }
}
Create a custom serializable data contract class, say DatabaseDistance, with following properties:
[DataMember(Name = "dbname")]
private string name;
[DataMember(Name = "distance")]
private double distance;
and use following method for deserialization:
public static T FromJSON<T>(string jsonValue, IEnumerable<Type> knownTypes)
{
//validate input parameters here
T result = default(T);
try
{
using (MemoryStream stream = new MemoryStream(Encoding.Unicode.GetBytes(jsonValue)))
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T), knownTypes);
result = (T)serializer.ReadObject(stream);
}
}
catch (Exception exception)
{
throw new Exception("An error occurred while deserializing", exception);
}
return result;
}
pass list of your objects as type parameter

Categories

Resources