Im trying to find an answer for this but i must be searching for the wrong terms.
Im working on a Windows phone app and am getting data from an API with a nested array value "user.username"
void data_arrived(object sender, DownloadCompleteData e)
{
String data = e.data;
JArray obj = JArray.Parse(data);
for (int i = 0; i < obj.Count; i++)
{
JObject row = JObject.Parse(obj[i].ToString());
var item = new DataList();
item.country = row["title"].ToString() + " (€" + row["price"].ToString() + ") ";
item.code = row["price"].ToString();
item.imageURL = row["urlimage"].ToString();
item.votes = row["votes"].ToString();
item.category = row["category"].ToString();
item.username = row["user.username"].ToString();
list.Items.Add(item);
}
}
Everything else works fine except user.username
How do i use this properly?
Thanks
You can deserialize a valid JSON string to a dynamic object. This will allow you access to underlying object using dot notation. e.g.
dynamic row = JsonConvert.DeserializeObject (obj[i].ToString());
Your final code block inside loop will look like
dynamic row = JsonConvert.DeserializeObject(obj[i].ToString());
Console.WriteLine(row.title.ToString() + " (€" + row.price.ToString() + ") ");
Console.WriteLine(row.price.ToString());
Console.WriteLine(row.urlimage.ToString());
Console.WriteLine(row.votes.ToString());
Console.WriteLine(row.category.ToString());
Console.WriteLine(row.user.username.ToString());
Console.WriteLine();
Console.WriteLine("-----------------------------\n");
There is no "easy" way to achieve this because the . in C# is reserved.
However, you could achieve something pretty close by using a dictionary and collection initializer. It's still somewhat isolated, and doesn't require you to create a custom class.
var obj = new Dictionary<string, object>
{
{ "user.username", "myvalue" }
};
var json = JsonConvert.SerializeObject(obj);
//{"user.username":"myvalue"}
Related
Im struggling with a json object.
I create the object (RO) with the following code and that Works fine.
string reply = #"" + client.UploadString(url, "POST", LS_json);
RootObject RO = new RootObject();
RO = JsonConvert.DeserializeObject<RootObject>(reply);
RO now contains all the data I have recieved through the json search.
Now, when iterating through the object the foreach iterate one more than (RO) contains:
cnt_V = 0;
foreach (object obj_attributtertype in RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter[cnt_V].type)
{
if (Convert.ToString(RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes[cnt_V].values[0].value);
}
cnt_V++;
}
The thing is that when cnt_V == 4 and "points" to the last entry attributes[cnt_V] then LS_ande is filled as supposed (=="KEY_VALUES").
But then the foreach iterates again (cnt_V == 5), no problem here, but when it is assigned to LS_ande then it dumps (of cource because there is no entry with data for cnt_V == 5).
I dont understand whats wrong. Please be gentle with me and feel free to ask for further information.
Thanks in advance.
While I can't answer this definitively because I don't have the data, this is what I would start with:
//take out the long and lengthy parts to make the rest clearer
//I see there are two things here, intentional?
var something = RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter;
var somethingElse = RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes;
cnt_V = 0;
//Here, you are iterating over something[cnt_V].type, but also change cnt_V in the body.
//Are you sure this is correct?
foreach (object obj_attributtertype in something[cnt_V].type)
{
if (Convert.ToString(somethingElse[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(somethingElse[cnt_V].values[0].value);
}
cnt_V++;
}
And looking at it that way, here is my stab in the dark.
Iterate with a for over the Count() of items in something
var something = RO.hits.hits[0]._source.Biz.Rel[cnt_I].org[cnt_III].mem[cnt_IV].attributter;
var somethingElse = RO.hits.hits[0]._source.Biz.Rel[cnt_I].mem[cnt_III].xsData[cnt_IV].attributes;
for (var cnt_V = 0; cnt_V < something.Count(); ++cnt_V)
{
if (Convert.ToString(somethingElse[cnt_V].type) == "KEY_VALUES")
{
LS_ande = "" + Convert.ToString(somethingElse[cnt_V].values[0].value);
}
cnt_V++;
}
I have a variable results which holds ResultView as shown below:
In turn StoryQ.Execution.Result IEnumerable will hold values:
I need to extract text representation like " Story is Story". How can I achieve this. Could anyone help me on this. Thanks
Solution is to use select in conjunction with string format.
.Select( c => new {Story_Prefix_Text = string.Format("{0} {1}" ,c.Prefix, c.Text)})
or without lambda
from currentpath in collection
select new { Story_Prefix_Text = currentpath.Prefix + " " + currentpath.Text };
Answering my own question just in case it would help somebody in future.
The problem was solved by converting IEnumerable to List and then iterating through foreach loop. Code snippet is below:
var textFormat = ((IStepContainer)v).SelfAndAncestors().Reverse().ToList();
foreach (var text in textFormat)
{
var StoryInText = text.Step.Prefix + " " + text.Step.Text;
}
I want to know the quickest and simplest way to sort the code shown below. Sorting from newRecord.AppCode would not be suitable as it will change the meaning of the output. So I need to sort every line from string outp. What would be the best way? Also I would like to make every row distinct. I beleive using LINQ would be very quick but I am not that great at it. Help appreciated. So close to getting it done! Note: Data is being pulled from a tsv. Using .net 3.5, visual studio 2008) Will mark answer as soon as I get progress. :)
while ((line = sr.ReadLine()) != null)
{
String[] splitted = line.Split('\t');
appcodes.Add(line);
Records newRecord = new Records();
newRecord.Server = splitted[0];
newRecord.Instance = splitted[1];
newRecord.AppCode = splitted[2];
newRecord.Database = splitted[3];
listrecords.Add(newRecord);
for (int i = 0; i < appcodes.Count(); i++)
{
if (newRecord.AppCode==appcodes[i].ToUpper())
{
String outp = newRecord.AppCode + " " + newRecord.Server + " " + newRecord.Instance + " " + newRecord.Database;
Console.WriteLine(outp);
}
}
}
have lists named Keepers and newkeepers. Was trying to do something like outp.sort() and outp.sort() but it doesnt work in strings. This is how I solved the problem.
Keepers.Add(outp);
Keepers.Sort();
newKeepers = Keepers.Distinct().ToList();
foreach (object o in newKeepers)
{
Console.WriteLine(o);
}
Console.ReadLine();
As you can see, newrecords contain different fields so I wrote a LINQ statement to solve the problem.
var sorted_list = (from r in newrecords
orderby r.AppCode, r.Server, r.Instance, r.Database
select r).Distinct().ToList();
var distinctSortedList = sorted_list.Distinct().ToList();
I've seen many posts about creating ExpandoObject objects and such, but it does not work in my case. I need to create an object like
var someObj = new {
term1 = "someValue",
term2 = "other",
...
};
Basically, we are using Dapper and we need to create a query dynamically, where the WHERE clause is fabricated from a given array of arguments. We are not generalizing queries! It's a single method receiving a variable number of arguments and we need to check OR each value on a single column.
Right now, the only viable solution is to revert and directly use System.Data.SqlClient.SqlConnection, or is there any way to make this work?
Update:
This is what most likely should work, but doesn't :
string inWhere = null;
dynamic inTerms = new ExpandoObject();
IDictionary<string, object> inTermsDict = inTerms;
if (!(string.IsNullOrEmpty(filter.Term) || string.IsNullOrWhiteSpace(filter.Term))) {
inWhere = "(" + string.Join(" OR ", filter.Terms.Select((t, i) => "{0} LIKE #p" + i)) + ")";
int termIndex = 0;
foreach (string term in filter.Terms) {
inTermsDict.Add("p" + (termIndex++), term);
}
}
// ...
var rows = db.Query("SELECT * FROM {table} WHERE {baseCondition}" +
(string.IsNullOrEmpty(inWhere) ? "" : string.Format(" AND " + inWhere, "columnName")),
inTerms as object);
Just to answer my own question, as we found the proper solution earlier today.
Simply put, we found the IDynamicParameters And this class simply solves everything, acting as a Dictionary.
var inTerms = new Dapper.DynamicParameters();
inTerms.Add("#p" + (termIndex++), somveValue);
Everyone's happy!
A more simple example might be:
List <myElement> Elements;
Elements.Add(my1);
Elements.Add(my2);
my1 and my2 eache have a variable of type string named myString
Now I want to change the value of my1.myString. But if I change it the value my2.myString gets changed aswell.
Hopefully it's a bit clearer now
I'm using a List with several Elements within it in C#. The List has as type a self-defined class with several variables in it.
Now I want to change in one list-element the value of a variable. But unfortunately the value gets replaced not only on this but in all elements of this list.
Any advice on how to fix this?
MyProjectElement File1 = this.Project.Elements[0];
MyProjectElement File2 = this.Project.Elements[1];
MyProject my1 = (MyProject)File1;
MyProject my2 = (MyProject)File2;
PageCount_F1 = my1.PageCount;
PageCount_F2 = my2.PageCount;
if (PageCount_F1 != PageCount_F2)
MessageBox.Show("The 2 files need to have the same file length", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
else
{
my1.IncludeAllPages = false;
my2.IncludeAllPages = false;
for(int i=1; i <= PageCount_F1; i++)
{
StringBuilder value1 = new StringBuilder();
StringBuilder value2 = new StringBuilder();
value1.Append("" + i);
value2.Append("" + (PageCount_F2-i+1));
MyProject my1new = new MyProject();
MyProject my2new = new MyProject();
my1new.Pages = value1.ToString();
my2new.Pages = value2.ToString();
my1.Pages = my1new.Pages;
my2.Pages = my2new.Pages;
this.Project.Elements.Add((myProjectElement)my1);
this.Project.Elements.Add((myProjectElement)my2);
((MyProject)this.Project.Elements[1]).Pages.Remove(0);
((MyProject)this.Project.Elements[i]).Pages.Remove(0);
((MyProject)this.Project.Elements[1]).Pages = "" + 1;
((MyProject)this.Project.Elements[PageCount_F2 - i + 1]).Pages = "" + (PageCount_F2 - i + 1);
((MyProject)this.Project.Elements[i-1]).Pages.Remove(0);
((MyProject)this.Project.Elements[i]).Pages.Remove(0);
((MyProject)this.Project.Elements[i - 1]).Pages = "" + i;
((MyProject)this.Project.Elements[i]).Pages = "" + (PageCount_F2 - i + 1);
}
You need to specify what the condition is to make a change. For example:
myList.ForEach(x => if(whateverCondition) x.myString = "blah" );
But you really need to ascertain what that condition is.
The problem is that in the code that you've put up you're changing your values in a loop that steps through every element and the loop starts indexing the List with index 1, whereas the first element in index 0.
If you're only after changing one element then select that element. Moo-Juice has posted a good suggestion (+1 btw).
p.s. don't post links to external stores with your code, many users that sit behind corporate firewalls can't access them.