I'm currently trying to add a item to a array. But I think a list would be way easier since I could use
list.Add("whatever");
Is there a way to receive the following as a list?
dynamic reps = JsonConvert.DeserializeObject("rep.json");
Example json:
{"reps": {
{
"username": "usera",
"reps": 10,
"latestrep": "userx"
},
"userb": {
"username": "userb",
"reps": 10,
"latestrep": "userx"
},
"userc": {
"username": "userc",
"reps": 10,
"latestrep": "userx"
}
}}
I appreciate any kind of help
Providing you have a class defining the list item:
public class UserReps
{
public string Username { get; set; }
public int Reps { get; set; }
public string LatestRep { get; set; }
}
You can achieve what you want with LINQ:
IDictionary<string, IDictionary<string, UserReps>> parsed = JsonConvert.DeserializeObject<IDictionary<string, IDictionary<string, UserReps>>>(json);
List<UserReps> userReps = parsed["reps"].Select(ur => ur.Value).ToList();
I think you are looking for something like this:
`
public static dynamic FromJsonToDynamic(this object value)
{
dynamic result = value.ToString().FromJsonToDynamic();
return result;
}
`
That is an extension method that I use for generic objects. If you are looking at something to convert it to a particular object you could create an extension method like this:
public static T FromJson<T>(this object value) where T : class
{
T result = value.ToString().FromJson<T>();
return result;
}
With your data as it is at the moment, no. Your input data doesnt appear to be a collection or something that could logically be 'listified'.
Related
How do I return a set of data from two static arrays(String, Decimal) to a view? Example [Small, 1.00], [Medium, 3.00], [Large, 7.50].
I have been looking at Tuple<> which does return the data to the controller but I don't think it is the correct method as I would have to create new properties in my Viewmodel to then assign data to return to view.
class :
public class BoxSizeViewModel
{
public static Tuple<string[], decimal[]> GetDetails()
{
string[] Size = { "S", "M", "L" };
decimal[] Price = { 1, 3, 7.50 };
return new Tuple<string[], decimal[]>(Size, Price);
}
}
I Am trying to assign the size and price to IEnumerable that I can return to a view.
I think you would be better off using a new class or struct for holding the info you want to display. Still, if you want to use tuples, you should return a List of Tuples, instead of a Tuple of strings, like so:
List<Tuple<string, decimal>>
I still believe this will be more readable though:
public class ProductInfo
{
public string Size { get; set; }
public decimal Price { get; set; }
}
public static List<ProductInfo> GetDetails()
{
...
}
As for the matter of combining your lists, the Linq Zip operation is what you need.
Check the code here: https://dotnetfiddle.net/qyryvY
I have a JSON string in below format for which I want to deserialize it into C# List. But the record number "1","2","3" (it can be upto 1,2,3...n depends on the json response each time) in JSON restricting me to deserialize it into C# object using Newtonsoft.Json
{
"1":{
"UID":"1",
"LICENCENO":"licenseno",
"NAME":"ABC"
},
"2":{
"UID":"2",
"LICENCENO":"licenseno",
"NAME":"PQR"
},
"3":{
"UID":"3",
"LICENCENO":"licenseno",
"NAME":"XYZ"
}
}
I am using below code for deserialization
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<DriverMaster>>(json);
I have DriverMaster class created as-
public class DriverMaster
{
public string UID { get; set; }
public string LICENCENO { get; set; }
public string NAME { get; set; }
}
Deserialization line giving unhandled exception, I know I am doing it in wrong way, because DriverMaster json object cannot be extracted into c# directly without doing something to record number 1,2,3...n in c#. Can anyone please help me to sort it out? Thanks in advance.
You were close:
var result = JsonConvert.DeserializeObject<Dictionary<string, DriverMaster>>(json)
.Select(x => x.Value)
.ToList();
Solution.
Change your code to use...
var result = JsonConvert.DeserializeObject<Dictionary<int, DriverMaster>>(json);
Explaination
The type is not the same... The List<DriverMaster>type will convert to JSON like so...
{
"1":
{
"DriverMaster": {
"UID":"1",
"LICENCENO":"licenseno",
"NAME":"ABC"
}
}
}
This doesn't match what you showed in your question...
The type that you are looking for is actually Dictionary<int, DriverMaster>, which is a key/value pair which will output a JSON string like so
{
"1": { ... },
"2": { ... },
"3": { ... }
}
In order to fix that, you need to use the Dictionary<int, DriverMaster> type instead.
For these types of things I like to use the often overlooked feature of JToken.SelectTokens. This function allows you to select tokens within a json string and permits the use of wildcards.
Here's some code that will deserialize your sample by selecting past the 1,2,3...N in the json:
public static IEnumerable<DriverMaster> Deserialize(string json)
{
return JToken.Parse(json).SelectTokens("*")
.Select(jToken => jToken.ToObject<DriverMaster>());
}
The * basically says to select all tokens after the root, so it's selecting the values associated with 1, 2, 3.. etc... Here's another SO answer that shows a more complicated usage of the SelectTokens method.
You need to use
public class DriverMaster
{
public string UID { get; set; }
public string LICENCENO { get; set; }
public string NAME { get; set; }
}
public class Root
{
[JsonExtensionData]
public IDictionary<string,JToken> Data {get;set;}
}
and
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<Root>(json);
If you want to have result as List, you can parse the result as.
var list = new List<DriverMaster>();
foreach(KeyValuePair<string, JToken> token in result.Data)
{
list.Add(token.Value.ToObject<DriverMaster>());
}
That would give you the desired result as
1 licenseno ABC
2 licenseno PQR
3 licenseno XYZ
I am stuck while returning api result, I have a class like
public partial class Sample
{
[JsonProperty("classificator")]
public List<Classificator> Classificator { get; set; }
}
public partial class Classificator
{
[JsonProperty("Value")]
public string Value { get; set; }
[JsonProperty("Description")]
public string Description { get; set; }
}
Let's say GetJson method retrieve our data from the database, there are 2 records and the data like
-- Value - Description
1- A - AXA
2- B - BXA
response = GetJson(); // this method gets data from db
return Content(HttpStatusCode.OK, response);
when I return this, it's like
{
"classificator": [{
"Value": "A",
"Description": "AXA"
}, {
"Value": "B",
"Description": "BXA"
}
]
}
but I would like to see like, I want to see bellowing result;
{
"classificator": [{
"A": "AXA"
}, {
"B" : "BXA"
}
]
}
I would like to ask you maybe someone knows a good practice or document(tutorial) about it.
I solve it by using, Dictionary < string, model >
but I need to return a huge nested field I cant implement this solution for all different nodes.
I solved by using Dictionary< string, object >
I put 2 nested objects inside of an object value. In my case it looked some complex I refactor and try to work through readable dictionary hierarchy.
basically for this example it something like below,
Dictionary<string, object> fooDict = new Dictionary<string, object>();
fooDict.Add("A", "AXA"); // in my case I put 2 nested object to value field
fooDict.Add("B", "BXA");
var serializedObject = JsonConvert.SerializeObject(fooDict);
using (System.IO.StreamWriter file = new System.IO.StreamWriter(#"C:\xxx\result.txt", true))
{
file.WriteLine(serializedObject);
}
I'd like to convert a List<some_object> to JSON.
public class some_object
{
public string field1 {get; set;}
public string field2 {get; set;}
}
I want to serialize this:
var somejson = new {
some_objects = new List<some_object>() {...some items...};
}
Standard serialization produces an array:
{
"some_objects": [
{
"field1":"value1",
"field2":"value2"
},
{
"field1":"value3",
"field2":"value4"
}
]
}
Instead, I want to produce something like this (more XML-like):
{
"some_objects":
{
"some_object": {"field1":"value1", "field2":"value2"},
"some_object": {"field1":"value3", "field2":"value4"}
}
}
Is there any way of producing this result?
No, JSON object properties need to be unique
All of the properties of your objects need to be different. Conceptually, XML represents an object, but the tags don't directly link to the concept of a property. The JSON way to do this would be what you posted:
{
"some_objects": [
{"field1":"value1", "field2":"value2"},
{"field1":"value3", "field2":"value4"}
]
}
Alternatively, use a dictionary giving items unique names
If you want to give each item a name that can then be used to access them, you can use a dictionary:
var dict = new {
some_objects = new Dictionary<string,some_object>(){
{ "a" , new some_object { field1="value1",field2="value2" } },
{ "b" , new some_object { field1="value3",field2="value4" } },
}
}
This would serialize into:
{
"some_objects":
{
"a": {"field1":"value1", "field2":"value2"},
"b": {"field1":"value3", "field2":"value4"}
}
}
no, because you will get objects with the same name, called: some_object
think... if you could do it, how you will refer to one of them, using some_objects.some_object how do you know which is?
It seems like you want to store some kind of metadata, specifically the type of object, where with XML you could use an attribute. You would have to do something like add a separate property:
public class some_object
{
public string typeText { get { return GetType().ToString(); } }
public string field1 { get; set; }
public string field2 { get; set; }
}
Which would theoretically generate JSON that looks something like:
{
"some_objects": [
{
"typeText":"MyNamespace.some_object",
"field1":"value1",
"field2":"value2"
},
{
"typeText":"MyNamespace.some_object",
"field1":"value3",
"field2":"value4"
}
]
}
Depending on your needs, you might want to encapsulate this metadata into its own class.
I am currently using a list to handle a JSON string which works fine for one instance of this, as can be seen below. What I want to do is make these methods that handle the conversion completely generic so I can use them for multiple JSON strings.
This is a snippet of my current code as it stands.
public class GetPerson
{
public string fooName { get; set; }
public string fooAddress { get; set; }
public string fooPosition { get; set; }
}
public class GetPosition
{
public string fooTitle { get; set; }
public string fooDepartment { get; set; }
public string fooSalary { get; set; }
}
private static List<GetPerson> ConvertToList(string jsonString)
{
List< listJson = new List<JsonObject>();
listJson = (List<GetPerson>)JsonConvert.DeserializeObject<List<GetPerson>>(jsonString);
return listJson;
}
This is just a quick sample but the List<GetPerson> is what I need to be generic so it can be reused, because as it stands the GetPosition will obviously not work with this, as I would want to be able to iterate through my code changing the type accordingly.
Is there a way I can assign a variable as a type? I saw another question about this but it didn't go into detail. Or is there another way that this could be achieved?
Thanks in advance.
Very Simple. You just have to make ConvertToList() generic and pass the desired class as Type Paramter in ConvertToList()
private static List<T> ConvertToList<T>(string jsonString)
{
var listJson = new List<JsonObject>();
listJson = (List<T>)JsonConvert.DeserializeObject<List<T>>(jsonString);
return listJson;
}
var personList = ConvertToList<GetPerson>(jsonString);
var positionList = ConvertToList<GetPosition>(jsonString);
You can use Generics to help make the ConvertToList function reusable for different types
private static List<T> ConvertToList<T>(string jsonString)
{
return (List<T>)JsonConverty.DeserializeObject<List<T>>(jsonString();
}
You can now call it using both GetPerson and GetPosition as the generic type.
var listOfPeople = ConvertToList<GetPerson>(personJson);
var listOfPositions = ConvertToList<GetPosition>(positionJson);
You can read more about Generics on MSDN.
Also, if all that you want to do is to [de]serialize JSON, you might want to consider a third-party library for that like JSON.net, Jil or ServiceStack.Text, all of which have built in functions to do what you are trying to do.