I'm having trouble pulling individual address components from google map's api results.
Here are the results received from this url:
http://maps.googleapis.com/maps/api/geocode/json?address=jobing.com+glendale+arizona&sensor=false
This url is in the "uri" variable. Here's the code I'm using to try and retrieve the address_component by type. Take into consideration that I'm a bit new at c#.
String Output = client.DownloadString(uri);
Dictionary<String, Object> RinkData = JsonConvert.DeserializeObject<Dictionary<String, Object>>(Output);
Dictionary<String, Object> RinkDataResults = (Dictionary<String, Object>) RinkData["results"];
if (RinkDataResults.ContainsKey("formatted_address"))
{
Route = GetAddressComponentByType(RinkDataResults["address_components"], "route");
}
And here is the function I'm using "GetAddressComponentByType"
protected String GetAddressComponentByType(Object AddressComponents, String AddressType)
{
Boolean MatchFound = false;
String MatchingLongName = "";
Dictionary<String, Object> AddressComponentsDict = (Dictionary<String, Object>)AddressComponents;
foreach (KeyValuePair<String, Object> ac in AddressComponentsDict)
{
Dictionary<String, Object> acDict = (Dictionary<String, Object>) ac.Value;
ArrayList acTypes = (ArrayList) acDict["types"];
foreach (String acType in acTypes)
{
if (acType == AddressType)
{
MatchFound = true;
break;
}
}
if (MatchFound)
{
MatchingLongName = (String) acDict["long_name"];
}
}
return MatchingLongName;
}
The problem is, it doesn't even get to my component retrieval function. It bombs converting RinkData["results"] to a Dictionary saying it's an invalid conversion.
Does anyone see what I'm doing wrong? Or maybe someone has a custom object I can read google maps geocode results into that works?
Ah, nevermind. I can extract address components easily if I start with this object
dynamic googleResults = new Uri(uri).GetDynamicJsonObject();
foreach (var result in googleResults.results)
{
foreach (var addressComp in result.address_components)
{
Literal1.Text += "<br />" + addressComp.long_name;
}
}
It's an extension class for JSON.NET found here. From L.B.'s answer to this question.
Related
I'm working on a project where I want to build tokens from a JSON Array.
//Data fed to the system
{"Fruits":[{"Number":"111", "Name":"Apple"}, {"Number":"112", "Name":"Orange"},{"Number":"113", "Name":"Peach"}]}
//serializes the http content to a string
string result = Request.Content.ReadAsStringAsync().Result;
//deserializes result
Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(result);
//builds custom tokens
var customTokens = new Dictionary<string, object>();
foreach (var dataField in data)
{
if (dataField.Value is JArray)
{
string nameValue = "";
foreach (JObject content in dataField.Value.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
nameValue += prop.Name.ToString() + " : " + prop.Value.ToString();
}
}
customTokens.Add($"{dataField.Key}", nameValue);
}
}
The above code managed to create token $Fruits.
But i also want to achieve token $Number and $Name, where values of each token is from the concatenated values of same key. Example, If I use the "$Number", it will be replaced by 111, 112, 113 and If I use the $Name, it will be replaced by Apple, Orange, Peach.
Also, I'm not using any strongly type models as I don't know what data will be fed to the system.
Any help?
There are a few minor changes to your code to achieve this. First make your dictionary look like this:
var customTokens = new Dictionary<string, List<string>>();
Then, when you loop over all the properties in the array, check if the property has been added, and if not add it.
foreach (JProperty prop in content.Properties())
{
if(customTokens.ContainsKey(prop.Name))
{
customTokens[prop.Name].Add(prop.Value.ToString());
}
else
{
customTokens.Add(prop.Name, new List<string> { prop.Value.ToString() });
}
}
At the end you have a dictionary where the key is the property name and the value is a List<string> - this can be concatenated together:
foreach(var item in customTokens)
{
Console.WriteLine(item.Key + ":" + String.Join(",", item.Value));
}
Or, if you really want it in a dictionary of concatenated strings just do this
var finalResult = customTokens.ToDictionary(k => k.Key, v => String.Format(",",v.Value));
Note you'll need to add using System.Linq to the top of your file to use ToDictionary
Final test code:
var result = "{ \"Fruits\":[{\"Number\":\"111\", \"Name\":\"Apple\"}, {\"Number\":\"112\", \"Name\":\"Orange\"},{\"Number\":\"113\", \"Name\":\"Peach\"}]}";
Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(result);
var customTokens = new Dictionary<string, List<string>>();
foreach (var dataField in data)
{
if (dataField.Value is JArray)
{
foreach (JObject content in dataField.Value.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
if(customTokens.ContainsKey(prop.Name))
{
customTokens[prop.Name].Add(prop.Value.ToString());
}
else
{
customTokens.Add(prop.Name, new List<string> { prop.Value.ToString() });
}
}
}
foreach(var item in customTokens)
{
Console.WriteLine(item.Key + ":" + String.Join(",", item.Value));
}
}
}
I have below json in string as parameter to a WebMethod.
How can I deserialize in such a way that value comes in Key value pair.
Json String Parameter:
["Ref No,0","Date,0","Amt,0","Sender Name,0","Sender Add,0","Beneficiary Name,0","Beneficiary Add,0","Phone,0","Secret Code,0","Secret Ans,0","Preferred Id,0"]
WebMethod:
[System.Web.Services.WebMethod]
public static string SaveMappings(string mappingData)
{
//string str = "{\"Arg1\":\"Arg1Value\",\"Arg2\":\"Arg2Value\"}";
//JavaScriptSerializer serializer = new JavaScriptSerializer();
//object obj;
//var data = serializer.Deserialize(mappingData,);
var data = mappingData.ToArray();
if (data != null)
{
}
var d2 = mappingData.Split(',');
if (d2!=null)
{
}
return mappingData;
}
If you need to work with JSON data then use Newtonsoft.JSON library.
Convert the object to an array of strings and then split every line.
With this approach you can be sure that the given string is actually an JSON array and it is correct.
var str = "[\"Ref No,0\",\"Date,0\",\"Amt,0\",\"Sender Name,0\",\"Sender Add,0\",\"Beneficiary Name,0\",\"Beneficiary Add,0\",\"Phone,0\",\"Secret Code,0\",\"Secret Ans,0\",\"Preferred Id,0\"]";
string[] objs = JsonConvert.DeserializeObject<string[]>(str);
Dictionary<string, string> dic = new Dictionary<string, string>();
foreach (var obj in objs)
{
var keyValue = obj.Split(',');
dic.Add(keyValue[0], keyValue[1]);
}
foreach (var record in dic)
{
Console.WriteLine("{0} => {1}", record.Key, record.Value);
}
Or this one using LINQ. It looks better and it can be written faster. However, it is less optimal (two calls of Split instead of one).
public Dictionary<string, string> FromJsonArray(string jsonArray)
{
return JsonConvert.DeserializeObject<string[]>(jsonArray)
.ToDictionary(obj => obj.Split(',')[0], obj => obj.Split(',')[1]);
}
// ...
var str = "[\"Ref No,0\",\"Date,0\",\"Amt,0\",\"Sender Name,0\",\"Sender Add,0\",\"Beneficiary Name,0\",\"Beneficiary Add,0\",\"Phone,0\",\"Secret Code,0\",\"Secret Ans,0\",\"Preferred Id,0\"]";
foreach (var record in FromJsonArray(str))
{
Console.WriteLine("{0} => {1}", record.Key, record.Value);
}
why don't you just change every ',' in the string array to ':' then pass it to the method, from what you wrote in the question, this should work
I'm actually trying to check if a string is equal to any of the key's in my Dictionary object.
Here is what I have done so far:
using (var oStreamReader = new StreamReader(path))
{
Dictionary<String, String> typeNames = new Dictionary<string, string>();
typeNames.Add("Kind","nvarchar(1000)");
typeNames.Add("Name","nvarchar(1000)");
DataTable oDataTable = new DataTable();
var headLine = oStreamReader.ReadLine().Trim().Replace("\"", "");
var columnNames = headLine.Split(new[] { ';' });
String[] oStreamDataValues;
/*
*create DataTable header with specific datatypes and names
*/
int countCol = 0;
foreach (string readColumn in columnNames)
{
if ((readColumn.ToString().Replace("\"", "").CompareTo(typeNames) == true))
{
// this comparison doesn't work
}
}
}
I am not quite sure what exactly you are trying to achieve. If you have a C# dictonary you can use linq to check for values that match the required value, e.g.
string valueToCompare = "Value to match";
Dictionary<string, string> dict = new Dictionary<string, string>
{
{"Key 1", "A value"},
{"Key 2", "Another value"}
};
bool found= dict.Values
.Any(value
=>
value.Equals(valueToCompare,
StringComparison.CurrentCultureIgnoreCase)
);
Since you want check if exist an entry in your Dictionary that as the same key of one of the values in your columnNames object I suggest you to use ContainsKey method
Dictionary<string, string> d = new Dictionary<string, string>();
string keyvalue;
if (d.ContainsKey("value to find"))
{
if (d.TryGetValue("value to find", out keyvalue))
{
//// here keyvalue variable has the value
}
else
{
///value is null or throws exception
}
}
else
{
////key no exists
}
I have solved this (by inspiration of Paul Houlston and Thomas Lielacher)
string headLine = oStreamReader.ReadLine().Trim().Replace("\"", "");
string columnNames = headLine.Split(new[] { ';' });
foreach (string readColumn in columnNames)
{
if (typeNames.Keys.Contains(readColumn, StringComparer.CurrentCultureIgnoreCase) == true)
{
DataColumn oDataColumn = new DataColumn(readColumn,typeof(System.String));
oDataTable.Columns.Add(oDataColumn);
}
}
I am surely missing something small here. I am trying to open multiple resx files, load them into a dictionary, then cross reference a translation file. The problem is that when I open up the resx file with resxResourceReader, it reads in all the the form setup data as well. I.E. container information, control names, etc.
Now I noticed in the resx file that the entries I want have "xml:space" along with them. What is the correct way to only get the strings I want, and leave all the other stuff behind?
Thanks!
foreach (String s in sourceLocations)
{
Dictionary<string, string> sourceTemp = new Dictionary<string, string>();
Dictionary<string, object> Temp = new Dictionary<string, object>();
using (ResXResourceReader rsxr = new ResXResourceReader(s))
{
foreach (DictionaryEntry entry in rsxr)
{
string[] parts = s.Split('\\');
if (!entry.Key.ToString().Contains(">>"))
{
sourceTemp.Add(parts[parts.Count() - 1] + "_" + entry.Key.ToString(), entry.Value.ToString());
}
}
sources.Add(sourceTemp);
}
}
For anyone who runs into this later, this ended up working :
foreach (String s in sourceLocations)
{
Dictionary<string, string> sourceTemp = new Dictionary<string, string>();
Dictionary<string, object> Temp = new Dictionary<string, object>();
using (ResXResourceReader rsxr = new ResXResourceReader(s))
{
rsxr.UseResXDataNodes = true;
foreach (DictionaryEntry entry in rsxr)
{
string[] parts = s.Split('\\');
if ((!entry.Key.ToString().Contains(">>")))
{
if (isNodeString((ResXDataNode)entry.Value))
sourceTemp.Add(parts[parts.Count() - 1] + "_" + entry.Key.ToString(), getNodeValue((ResXDataNode)entry.Value));
}
}
sources.Add(sourceTemp);
}
}
private string getNodeValue(ResXDataNode node)
{
if (node.FileRef == null)
{
return node.GetValue((ITypeResolutionService)null).ToString();
}
else return String.Empty;
}
private bool isNodeString(ResXDataNode node)
{
string result = node.GetValueTypeName((ITypeResolutionService)null);
if (result.Contains("System.String")) return true;
else return false;
}
How could you convert a string of JSON to a C# NameValueCollection simply, preferably without using a 3rd party parser?
I'm not sure why everyone is still recommending JSON.NET for deserialization of JSON. I wrote a blog post on how to deserialize JSON to C#.
In short, it's like this:
using System.Web.Script.Serialization;
var jss = new JavaScriptSerializer();
var dict = jss.Deserialize<Dictionary<string, string>>(jsonText);
NameValueCollection nvc = null;
if (dict != null) {
nvc = new NameValueCollection(dict.Count);
foreach (var k in dict) {
nvc.Add(k.Key, k.Value);
}
}
}
var json = jss.Serialize(dict);
Console.WriteLine(json);
Be sure to add a reference to System.Web.Extensions.dll.
Note:
I usually deserialize to dynamic, so I'm assuming that NameValueCollection would work. However, I haven't verified if it actually does.
EDIT
Pure .net solution without third party development have look : JavaScriptSerializer – Dictionary to JSON Serialization and Deserialization
make use of Json.NET
string jsonstring = #"{""keyabc"":""valueabc"",""keyxyz"":""valuexyz""}";
Dictionary<string, string> values =
JsonConvert.DeserializeObject<Dictionary<string, string>>(jsonstring);
Check #jon answer suggest same : .Net Linq to JSON with Newtonsoft JSON library
If your JSON contains nested objects whithin it the solution below will handle them properly (based on JSON.NET, but you can adapt to the JSON parser of your choice).
This usage example:
var json = "{\"status\":\"paid\",\"date\":\"2019-10-09T17:30:51.479Z\",\"customer\":{\"id\":123456789,\"country\":\"br\",\"name\":\"Thomas Vilhena\",\"phone_numbers\":[\"+5511987654321\"],\"documents\":[{\"id\":\"doc_id\"}]}}";
var dict = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
var nvc = new NameValueCollection(dict.Count);
AddKeyValuePairs(nvc, dict);
Console.WriteLine(nvc["status"]);
Console.WriteLine(nvc["date"]);
Console.WriteLine(nvc["customer[phone_numbers][0]"]);
Console.WriteLine(nvc["customer[id]"]);
Console.WriteLine(nvc["customer[documents][0][id]"]);
Produces the following output:
paid
09.10.2019 17:30
+5511987654321
123456789
doc_id
And here's the implementation:
private static void AddKeyValuePairs(
NameValueCollection nvc,
Dictionary<string, object> dict,
string prefix = null)
{
foreach (var k in dict)
{
var key = prefix == null ? k.Key : prefix + "[" + k.Key + "]";
if (k.Value != null)
AddKeyValuePair(nvc, key, k.Value);
}
}
private static void AddKeyValuePair(
NameValueCollection nvc,
string key,
object value)
{
if (value is string || value.GetType().IsPrimitive)
{
nvc.Add(key, value.ToString());
}
else if (value is DateTime)
{
nvc.Add(key, ((DateTime)value).ToString("g"));
}
else
{
AddNonPrimitiveValue(nvc, key, value);
}
}
private static void AddNonPrimitiveValue(
NameValueCollection nvc,
string key,
object value)
{
var a = value as JArray;
if (a != null)
{
for (int i = 0; i < a.Count; i++)
AddKeyValuePair(nvc, key + "[" + i + "]", a[i]);
}
else
{
var v = value as JValue;
if (v != null)
{
AddKeyValuePair(nvc, key, v.Value);
}
else
{
var j = value as JObject;
if (j != null)
AddKeyValuePairs(nvc, j.ToObject<Dictionary<string, object>>(), key);
}
}
}