Parsing JSON to Controller in MVC - c#

I'm parsing a json which has 3 properties that have arrays as values, to my controller. I managed to save the json to a Dictionary, and now i need those 3 arrays to make a query to my database.
The setup is the following
public JsonResult FilterMultiselects(string json)
{
Dictionary<string, string[]> filters = JsonConvert.DeserializeObject<Dictionary<string, string[]>>(json);
string[] lines = filters["lines"];
string[] countries = filters["countries"];
string[] users = filters["users"];
var query = ... //do my query which returns the results i desire
string result = JsonConvert.SerializeObject(query, Formatting.Indented,
new JsonSerializerSettings {
PreserveReferencesHandling = PreserveReferencesHandling.Objects
});
return Json(result, JsonRequestBehavior.AllowGet);
}
The problem im having is that when i get to the part in which i initialize those 3 arrays only the second one(countries) exists. The other two dont even create which makes no sense to me. Even thought i have not worked with Dictionaries(hashes) too much in C# it looks good.
Could anyone help me with what am i missing?
The json im parsing has the following look:
{
lines: ["line 1", "line 2"]
countries: ["England"]
users: []
}
The string my controller receives is:
"{\"lines\":[\"line 1\",\"line 2\"],\"countries\":[\"England\"],\"users\":[]}"
The dictionary gets created and has 3 keys that have the correct arrays as values.

Related

C# serializing JSON data from Database for API

My goal is to get the data from the database, serializing them into JSON format and send it to the API. The problem is that I don't know how to get right JSON format for the API.
C# Worker service collecting data from database.
from database i got:
1|John|Wick|Action|101
my API needs this JSON:
{
"Name":"John",
"Surname":"Wick",
"Type":"Action",
"Length":"101"
}
when i use in C# serializing to JSON:
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(values);
i got:
[John,Wick,Action,101]
is there any way how to add name of values to JSON ?
First split the database result based on the delimiter
string dbResult = ...; //1|John|Wick|Action|101
string[] dbResults = dbResult.Split("|");
Second create an anonymous object (if you don't want to introduce a data model class/struct/record)
var result = new
{
Name = dbResults[0],
Surname = dbResults[1],
Type = dbResults[2],
Length = dbResults[3],
};
Third serialize the anonymous object
var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(result);

How to return a Json from a list in an api without the properties names in netcore

for some legacy code, I need to return a list of rows than come from a list of the element, but, the client needs it without the property name.
This is what I need. (I know that inside this JSON return, it's an array list then it's not a valid JSON, but is the way that needs to be received by the front end I don't know why
{ "success":true,"msg":"","draw":"1","recordsTotal":14,"recordsFiltered":14,
{ "data":
[
["Xiaomi","Redmi 8","10","6.0.1","","sadsadasd"],
["Xiaomi","Redmi 8","10","6.0.1","","sadsadasd"],
]
}
This is what I got now
{"success":true,"msg":"","draw":"1","recordsTotal":14,"recordsFiltered":14,
"data" :[
{"Brand":"Xiaomi","Model":"Redmi 8","Version":10,"App":"4.3.3","Phone":"","AsignedUSer":"ceererer"},
{"Brand":"Xiaomi","Model":"Redmi 8","Version":10,"App":"4.3.3","Phone":"","AsignedUSer":"ceererer"},
]
}
And this is the code how I am retrieving the data
return new JsonResult(new { success = true, msg = "", draw ="1", recordsTotal = listToReturn.Count(), recordsFiltered = listToReturn.Count() ,
data = listToReturn ,
});
You could project your list into arrays to extract the property values:
var data = listToReturn
.Select(d => new string[]{d.Brand, d.Model, d.Version, etc..})
.ToList();
Note that a "JSON" content without the property names will be a not valid JSON document.
What you need seems to be more like a CSV-like response.
Have you tried to format the result as CSV?

Getting the values from this specific JSON

I'm trying to get all of the "last" values from this JSON here:
{"btc":{
"usd": {
"bitfinex": {
"last": "1191.60",
"volume": "1.99324e+7"
},
"bitstamp": {
"last": "1193.06",
"volume": "8.73693e+6"
},
"btce": {
"last": "1174.27",
"volume": "6.03521e+6"
}
}
}
But for some reason I can only access "btc" and "usd". I can't get anything out of it including the "last" values. Here is the code i'm using:
private string GetPrice()
{
WebClient wc = new WebClient();
var data = wc.DownloadString("http://preev.com/pulse/units:btc+usd/sources:bitfinex+bitstamp+btce");
JObject o = JObject.Parse(data);
string response = o["btc"].ToString();
return response;
}
If I change it to:
o["last"].ToString();
It just doesn't return anything. Can someone please provide me with a solution? I also tried making a key/value dict out of it and looping over each pair. Did not work.
The JObject structure is similar to a class with properties, so the first-level indexer ["btc"] returns another object that you have to query for its own properties ["usd"]
You can also opt for using JObject.SelectToken, generally not a bad idea. Other answers have shown how to chain the indexers but that's hard to read and maintain. Instead you can do:
jObj.SelectToken("btc[0].usd[0].bitstamp[0].last").ToString();
Further you can use the power of this syntax for other queries:
// a list o all the 'last' values
jObj.SelectTokens("btc.usd.*.last").Select(t=>t.ToString()).ToList();
Another advantage, if you're building a more complex system, is that you could put the queries in a config file or attributes etc to make them more manageable or deploy logic changes without rebuilding.
Yet another approach would be to build your own class structure and deserialize your json into it, so you have strongly typed values (double instead of string for the values for example)
public class btc {
public usd usd {get;set;}
}
public class usd....
var btcLoaded = JsonConvert.DeserializeObject<btc>(jsonString);
var lastBitstamp = btc.usd.bitstamp.last;
Use: o["btc"]["usd"]["bitfinex"]["last"].ToString() to get the 'last' value of 'bitfinex'.
After parsing the JSON whenever you index the o variable you are indexing from the root of the JSON. In order to access nested properties like 'last' you will need to index into the next level of the JSON as such:
var bitfinex = o["btc"]["usd"]["bitfinex"]["last"].ToString();
var bitstamp = o["btc"]["usd"]["bitstamp"]["last"].ToString();
var btce = o["btc"]["usd"]["btce"]["last"].ToString();
To reduce the repetition you could iterate over the properties under the btc.usd field.
if u want to all last values use this..
decimal[] lastValues = obj.SelectTokens("$..last").ToArray()
.Select(a => a.Parent.ToObject<decimal>()).ToArray();
if u want to dictionary, use this..
var dictionary = obj["btc"]["usd"].Select(a =>
new
{
Key = ((JProperty)a).Name,
Value = a.First["last"].ToObject<decimal>()
})
.ToDictionary(a => a.Key, a => a.Value);

ASP.NET getting indexed values when deserializing JSON into a dynamic object

So I have a JSON string that I am passing from an AJAX call to my controller. I have a list of indexed values that I am passing into a dynamic object.
I deserialize the JSON with
JsonConvert.DeserializeObject<dynamic>(s)
This is the output from that dynamic object:
"RolePermissions[0].RolePermissionId": "269",
"RolePermissions[0].HasAccess": "false",
"RolePermissions[1].RolePermissionId": "270",
"RolePermissions[1].HasAccess": "false",
"RolePermissions[2].RolePermissionId": "271",
"RolePermissions[2].HasAccess": "true",
"RolePermissions[3].RolePermissionId": "272",
"RolePermissions[3].HasAccess": "false"
When I try to access the a property of the object with
ssObj.RolePermissions[0].RolePermissionId
I get a RuntimeBinderException. I have tried to use JObject.Parse, which works great, but for some reason, the values in the array become out of order.
Any help would be greatly appreciated. Thanks!
When you try to do RolePermissions[0].RolePermissionId you are trying to access a nested collection containing an object with a property RolePermissionId at index 0. But your JSON doesn't represent a hierarchy of objects, it represents a single flat object with key/value pairs whose keys contain periods and brackets. Since c# identifiers don't allow such characters so you have no way to access such property values using dynamic directly.
Instead, your options include:
Take advantage of the fact that JsonConvert.DeserializeObject<dynamic>(s) actually returns a JObject and use its dictionary indexer:
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
var rolePermissionId = (string)ssObj["RolePermissions[0].RolePermissionId"];
If you prefer a slightly more typed solution, you could deserialize to a Dictionary<string, dynamic>:
var ssDict = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(s);
var rolePermissionId = (string)ssDict["RolePermissions[0].RolePermissionId"];
Or for a much more statically typed solution, parse explicitly to a JObject and use LINQ to JSON:
var jObj = JObject.Parse(s);
var rolePermissionId = (string)jObj["RolePermissions[0].RolePermissionId"];
Sample fiddle showing the various options.
If you are in control of the data being sent via AJAX then make sure the data sent is properly formatted.
In order to be able to deserialize variable s like:
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
and access the resulting object in this manner:
ssObj.RolePermissions[0].RolePermissionId
then the JSON value in s, based on your sample and desired behavior, would have to look like this:
{
"RolePermissions": [
{
"RolePermissionId": "269",
"HasAccess": "false"
},
{
"RolePermissionId": "270",
"HasAccess": "false"
},
{
"RolePermissionId": "271",
"HasAccess": "true"
},
{
"RolePermissionId": "272",
"HasAccess": "false"
}
]
}
This quick unit test showed that it is possible to get indexed values when deserializing JSON into a dynamic object
[TestClass]
public class UnitTest1 {
[TestMethod]
public void GetIndexedValuesWhenDeserializingJSONIntoDynamicObject() {
var s = #"
{
'RolePermissions': [
{
'RolePermissionId': '269',
'HasAccess': 'false'
},
{
'RolePermissionId': '270',
'HasAccess': 'false'
},
{
'RolePermissionId': '271',
'HasAccess': 'true'
},
{
'RolePermissionId': '272',
'HasAccess': 'false'
}
]
}
";
var ssObj = JsonConvert.DeserializeObject<dynamic>(s);
var result = ssObj.RolePermissions[0].RolePermissionId;
Assert.AreEqual("269", (string)result);
}
}
So you need to make sure you are sending well formatted JSON to your controller to achieve desired behavior.

how to form JSON Object

I have a Table for categories , which stores Hierarchical Data in the following format
NodeID--->ParentID--->NodeName
I want to select categories in the following manner for which i need to return a JSON Object in a predefined format.
JSON FORMAT
"Option 1": {"Suboption":200},
"Option 2": {"Suboption 2": {"Subsub 1":201, "Subsub 2":202},
"Suboption 3": {"Subsub 3":203, "Subsub 4":204, "Subsub 5":205}
}
How do i return JSON in this format from a hierarchical database?? I mean how do i approach?? Kindly show me a direction.
NOTE:
Click Here to Checkout the (jQuery) Plugin I am using
Provided you are in ASP.Net you can just iterate though it using the build in functions:
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
string sJSON = oSerializer.Serialize(oList);
You can perform iterations using loops as well:
var productsJObject = JObject.Parse(result.Content.ReadAsStringAsync().Result);
foreach (var category in categories)
{
foreach (var category2 in category.Value)
{
foreach (var category3 in category2.Value)
{
var olist = new MyList { Id = version.SelectToken("id").ToString()
};
}
}
}
This can be ugly but usable if you have a defined set of levels, if you are performing an Nth dimensional transition it gets very complex very fast.
You can look here for an idea:
Java - Create JSON Object from Multiple Multidimensional Arrays

Categories