How to convert a dictionary pair.value to a dictionary in C#? - c#

i have the following JSON in my application.
string json = #"{""dest"":[ { ""mode"": ""1"", ""test"":""test1,test,test2""},{ ""mode"": ""2"", ""test"": ""test3"" }]}";
To get the value of dest I m using the following method.
var json_serializer = new JavaScriptSerializer();
Dictionary<string, object> dictionary = json_serializer.Deserialize<Dictionary<string, object>>(json);
public Dictionary<string, object> GetObject(Dictionary<string, object> view, string name)
{
Dictionary<string, object> result = new Dictionary<string, object>();
object value = null;
foreach (KeyValuePair<string, object> pair in view)
{
Type type = pair.Value.GetType();
if (pair.Key == name)
{
**Dictionary<string, object> child = (System.Collections.Generic.Dictionary<string, object>)pair.Value;**
result = GetObject(child, name);
if (result != null)
{
break;
}
}
else
{
}
}
return result;
}
I m getting error in the line Dictionary child = (System.Collections.Generic.Dictionary)pair.Value;.
The error says "Unable to cast object of type 'System.Collections.ArrayList' to type 'System.Collections.Generic.Dictionary`2[System.String,System.Object]'."
Anyone knows how to fix this?

Assuming tset in your array is a typo and it actually is test, you can use concerete classes ....
string json = #"{""dest"":[ { ""mode"": ""1"", ""test"":""test1,test,test2""},{ ""mode"": ""2"", ""test"": ""test3"" }]}";
var obj = new JavaScriptSerializer().Deserialize<MyObject>(json);
public class Dest
{
public string mode { get; set; }
public string test { get; set; }
}
public class MyObject
{
public List<Dest> dest { get; set; }
}

Related

Create a dictionary of a model?

It's quite hard for me to explain this, but I will give it a go.
Objective:
Create a LINQ query that will return a dictionary of data. However it must be a dictionary of the model which I am using.
View Model:
public class ValueBySupplierAndClaimTypeViewModel : ReportViewModel
{
public IQueryable<ValueBySupplierAndClaimTypeModel> ReportData {get; set; }
public TotalValueBySupplierAndClaimTypeModel ReportTotalData { get; set; }
public Dictionary<string, decimal> DictionaryData { get; set; }
public string output { get; set; }
}
Interface:
Dictionary<string, decimal> DictData;
TotalValueBySupplierAndClaimTypeModel GetTotalValueBySupplierAndClaimType(
int ClientID, int ReviewPeriodID, int StatusCategoryID);
SQL Repository:
public TotalValueBySupplierAndClaimTypeModel GetTotalValueBySupplierAndClaimType(int ClientID, int ReviewPeriodID, int StatusCategoryID)
{
var rt =
this.GetValueBySupplierAndClaimType(ClientID, ReviewPeriodID, StatusCategoryID);
TotalValueBySupplierAndClaimTypeModel x = new TotalValueBySupplierAndClaimTypeModel()
{
NormalTotal = rt.Sum(c=>c.Normal) ?? 0,
QueryTotal = rt.Sum( c => c.Query) ?? 0,
StrongTotal = rt.Sum( c => c.Strong) ?? 0
};
return x;
}
I'm really not sure how to do this. Can anybody help?
I have this function that converts an object to a dictionary. It gets all the properties of the class, as the dictionary's keys. May be you can modify it to meet your needs:
public Dictionary<string, object> ConvertClassToDict(object classToConvert)
{
Dictionary<string, object> result = new Dictionary<string, object>();
PropertyInfo[] properties = classToConvert.GetType().GetProperties();
List<string> propertiesNames = properties.Select(p => p.Name).ToList();
foreach (var propName in propertiesNames)
{
PropertyInfo property = properties.First(srcProp => srcProp.Name == propName);
var value = property.GetValue(classToConvert, null);
result.Add(propName, value);
}
return result;
}
The argument classToConvert, is just an instance of any class.
Similar to #lukiller's answer, but with LINQ:
public Dictionary<string, object> MapToDictionary(object instance)
{
if(instance == null) return null;
return instance.GetType()
.GetProperties()
.ToDictionary(p => p.Name,
p => p.GetValue(instance));
}
For example, let's suppose we have the following class:
public class User
{
public string Username { get; set; }
public string Password { get; set; }
}
We can print it like this (one line):
MapToDictionary(new User()
{
Username = "mcicero",
Password = "abc123"
}).ToList().ForEach(i => Console.WriteLine("{0}: {1}", i.Key, i.Value));
This prints out:
Username: mcicero
Password: abc123

Need explanation for some code.

What does
public object this[string name]
do
class ObjectWithProperties
{
Dictionary<string, object> properties = new Dictionary<string, object>();
public object this[string name]
{
get
{
if (properties.ContainsKey(name))
{
return properties[name];
}
return null;
}
set
{
properties[name] = value;
}
}
}
You will be able to reference the values in your dictionary directly from your object using indexes (ie, no property name)
In your case it would be
var foo = new ObjectWithProperties();
foo["bar"] = 1;
foo["kwyjibo"] = "Hello world!"
// And you can retrieve them in the same manner...
var x = foo["bar"]; // returns 1
MSDN guide: http://msdn.microsoft.com/en-gb/library/2549tw02.aspx
Basic tutorial: http://www.tutorialspoint.com/csharp/csharp_indexers.htm
Edit to answer question in comment:
This is equivalent to doing something like the following:
class ObjectWithProperties
{
public Dictionary<string, object> Properties { get; set; }
public ObjectWithProperties()
{
Properties = new Dictionary<string, object>();
}
}
// instantiate in your other class / app / whatever
var objWithProperties = new ObjectWithProperties();
// set
objWithProperties.Properties["foo"] = "bar";
// get
var myFooObj = objWithProperties.Properties["foo"]; // myFooObj = "bar"

Convert Nested for loops into Linq

Can any body convert the following nested forloop into linq query.
I have the following class definition.
public class MessageCodes
{
public string IdentityKey{ get; set; }
public Dictionary<string, string> LangCollection { get; set; }
public MessageCodes()
{
LangCollection = new Dictionary<string, string>();
}
}
IdentityKey in above class is unique, LangCollection can have multiple key, values.
Say
MessageCodes newCode = new MessageCodes()
{
MessageCode = "10",
LangCollection = new Dictionary<string, string>()
{
{"en","Hello"},
{"de","dello"},
{"fr","fello"},
}
};
MessageCodes oldCode = new MessageCodes()
{
MessageCode = "10",
LangCollection = new Dictionary<string, string>()
{
{"en","fello"},
{"de","pello"},
{"fr","fello"},
}
};
Above is an example of MessageCode Instance.
Now i have collection of NewMessageCodes and OldMessageCodes. I need to compare them
Following is the problem nested forloop,
foreach (MessageCodes newMessageCode in newDiffMsgCodeCollection)
{
foreach (MessageCodes oldMessageCode in oldDiffMsgCodeCollection)
{
if (newMessageCode.MessageCode == oldMessageCode.MessageCode)
{
MessageCodes msgCodes = new MessageCodes();
msgCodes.MessageCode = newMessageCode.MessageCode;
Dictionary<string, string> langCollection = new Dictionary<string, string>();
foreach (KeyValuePair<string, string> newLangNode in newMessageCode.LangCollection)
{
foreach (KeyValuePair<string, string> oldLangNode in oldMessageCode.LangCollection)
{
string newCode = newLangNode.Key.Trim().ToLower();
string oldCode = oldLangNode.Key.Trim().ToLower();
if (newCode == oldCode )
{
if (newLangNode.Value != oldLangNode.Value)
{
langCollection.Add(newCode, oldCode);
}
}
}
}
msgCodes.LangCollection = langCollection;
}
}
}
Convert the above code mess into a Linq query or Lambda expressions.
newDiffMsgCodeCollection.ForEach(pd => {
oldDiffMsgCodeCollection.ForEach(pds =>
{
if (pd.MessageCode == pds.MessageCode)
{
//business logic
}
});
});
I think this is pretty much what you want:
var messageCodesQuery =
from newMessageCode in newDiffMsgCodeCollection
from oldMessageCode in oldDiffMsgCodeCollection
where newMessageCode.MessageCode == oldMessageCode.MessageCode
select new MessageCodes()
{
MessageCode = newMessageCode.MessageCode,
LangCollection = (
from newLangNode in newMessageCode.LangCollection
from oldLangNode in oldMessageCode.LangCollection
let newCode = newLangNode.Key.Trim().ToLower()
let oldCode = oldLangNode.Key.Trim().ToLower()
where newCode == oldCode
where newLangNode.Value != oldLangNode.Value
select new { newCode, oldCode }
).ToDictionary(x => x.newCode, x => x.oldCode)
};
You just now need to make sure you do something with the results.

Create Json Array with ServiceStack

Quite new to .NET. Still haven't gotten the hang of how to do dictionaries, lists, arrays, etc.
I need to produce this JSON in order to talk to SugarCRM's REST API:
{
"name_value_list": {
"assigned_user_name": {
"name": "assigned_user_name",
"value": "joe"
},
"modified_by_name": {
"name": "modified_by_name",
"value": "jill"
},
"created_by_name": {
"name": "created_by_name",
"value": "jack"
}
}
}
from this C# POCO, which plays nicely with ServiceStack:
public class lead {
public string assigned_user_name { get; set; }
public string modified_by_name { get; set; }
public string created_by_name { get; set; }
}
I have to do this sort of conversion for lots of different classes, so I don't think it's wise to create another strongly typed class (ala Costomising the serialisation/serialised JSON in service stack)
I've looked through the ServiceStack docs, but maybe I missed an example of this somewhere.
How do I build this JSON in a way that I can extend to other ServiceStack POCOs?
This produces the right JSON:
Dictionary<string, Dictionary<string, string>> nameValues = new Dictionary<string, Dictionary<string, string>>();
// Deal with all the properties on the object
IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
foreach (PropertyInfo prop in props)
{
Dictionary<string, string> nameValue = new Dictionary<string, string>();
nameValue.Add("name", prop.Name);
object propValue = prop.GetValue(this, null);
if (propValue == null)
{
nameValue.Add("value", string.Empty);
}
else
{
nameValue.Add("value", prop.GetValue(this, null).ToString());
}
nameValues.Add(prop.Name, nameValue);
}
Dictionary<string, object> nameValuesArray = new Dictionary<string, object>();
nameValuesArray.Add("name_value_list", nameValues);
string jsonString = JsonSerializer.SerializeToString<Dictionary<string, object>>(nameValuesArray);
The reflection stuff is so that I can use it on any object later.
It's just a matter of constructing the right dictionary for the desired JSON output - in this case a dictionary -> dictionary -> dictionary. Trial and error... :/
Update
Altered it slightly (thanks paaschpa) to use a generic NameValue class because Dictionaries look ugly. I also got the requirements wrong. The JSON should be this:
[
{
"name": "id",
"value": "60e03cb3-df91-02bd-91ae-51cb04f937bf"
},
{
"name": "first_name",
"value": "FancyPants"
}
]
which you can do like this:
public class NameValue
{
public string name { get; set; }
public string value { get; set; }
}
public class Lead
{
public string assigned_user_name { get; set; }
public string modified_by_name { get; set; }
public string modified_user_name { get; set; }
public List<NameValue> toNameValues()
{
List<NameValue> nameValues = new List<NameValue>();
IList<PropertyInfo> props = new List<PropertyInfo>(this.GetType().GetProperties());
foreach (PropertyInfo prop in props)
{
NameValue nameValue = new NameValue();
object propValue = prop.GetValue(this, null);
if (propValue != null && !String.IsNullOrEmpty(propValue.ToString()))
{
nameValue.name = prop.Name;
nameValue.value = propValue.ToString();
nameValues.Add(nameValue);
}
}
return nameValues;
}
}
I'm leaving my original question as is (and my above answer) because it's still a legit example and proper JSON.
Well, I don't think .NET dictionaries, lists, arrays, etc. will be helpful since the JSON you listed doesn't appear to have any arrays (square brackets) it in. I'm guessing most .NET JSON serializers will use square brackets when it hits these types. So, I think this leaves creating your own classes or doing some type of 'string magic' to produce to JSON you need.
Not exactly sure how you are using ServiceStack to talk to SugarCRM, but doing something like below should have ServiceStack.Text.JsonSerializer produce the JSON string you listed.
public class NameValue
{
public string name { get; set; }
public string value { get; set; }
}
public class Lead
{
public NameValue assigned_user_name { get; set; }
public NameValue modified_by_name { get; set; }
public NameValue created_by_name { get; set; }
}
public class LeadRequest
{
public Lead name_value_list { get; set; }
}
public void JsonTest()
{
var req = new LeadRequest
{
name_value_list = new Lead
{
assigned_user_name = new NameValue {name = "assigned_user_name", value = "joe"},
modified_by_name = new NameValue {name = "modified_by_name", value = "jill"},
created_by_name = new NameValue {name = "created_by_name", value = "jack"}
}
};
var jsonReq = ServiceStack.Text.JsonSerializer.SerializeToString(req);
}
You could create a custom serializer for the lead class.
JsConfig<lead>.SerializeFn = lead => {
// Use reflection to loop over the properties of the `lead` object and build a dictionary
var data = new Dictionary<string, object>();
foreach (var property in typeof(lead).GetProperties()) {
data[property.Name] = new {
name: property.Name,
value: property.GetValue(lead, null);
};
}
return data.ToJson();
};
You could make this generic by having all classes that you want to serialize in this way implement a marker interface, for example ISugarCrmRequest, and register this custom serializer for all implementations of that interface.

looping through json array in c#

I have a json string like,
{"objectType" : "Subscriber", "objectList":[{"firstName":"name1","email":"email#example.com","address":"exampleAddress"},{"firstName":"name2","email":"email2#example.com","address":"exampleAddress2"}]}
I need to parse it in my C# code. I have tried,
JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject(myjson here);
But i cant loop through the "objectList" array. How it can be done?
var jsonObj = new JavaScriptSerializer().Deserialize<RootObj>(json);
foreach (var obj in jsonObj.objectList)
{
Console.WriteLine(obj.address);
}
public class ObjectList
{
public string firstName { get; set; }
public string email { get; set; }
public string address { get; set; }
}
public class RootObj
{
public string objectType { get; set; }
public List<ObjectList> objectList { get; set; }
}
Hint: You can use this site to convert your json string to c# classes
EDIT
using Json.Net
dynamic jsonObj = JsonConvert.DeserializeObject(json);
foreach (var obj in jsonObj.objectList)
{
Console.WriteLine(obj.address);
}
var routes_list = (Dictionary<string, object>)json_serializer.DeserializeObject(myjson);
foreach (var record in routes_list)
{
Console.WriteLine(record);
}
This worked for me, converts to JSON to YAML essentially
string JSONDeserialized {get; set;}
public int indentLevel;
private bool JSONDictionarytoYAML(Dictionary<string, object> dict)
{
bool bSuccess = false;
indentLevel++;
foreach (string strKey in dict.Keys)
{
string strOutput = "".PadLeft(indentLevel * 3) + strKey + ":";
JSONDeserialized+="\r\n" + strOutput;
object o = dict[strKey];
if (o is Dictionary<string, object>)
{
JSONDictionarytoYAML((Dictionary<string, object>)o);
}
else if (o is ArrayList)
{
foreach (object oChild in ((ArrayList)o))
{
if (oChild is string)
{
strOutput = ((string)oChild);
JSONDeserialized += strOutput + ",";
}
else if (oChild is Dictionary<string, object>)
{
JSONDictionarytoYAML((Dictionary<string, object>)oChild);
JSONDeserialized += "\r\n";
}
}
}
else
{
strOutput = o.ToString();
JSONDeserialized += strOutput;
}
}
indentLevel--;
return bSuccess;
}
usage
Dictionary<string, object> JSONDic = new Dictionary<string, object>();
JavaScriptSerializer js = new JavaScriptSerializer();
try {
JSONDic = js.Deserialize<Dictionary<string, object>>(inString);
JSONDeserialized = "";
indentLevel = 0;
DisplayDictionary(JSONDic);
return JSONDeserialized;
}
catch (Exception)
{
return "Could not parse input JSON string";
}

Categories