My API response will return a list of JSON objects and I need to verify the order of the list, so I write a function as follows. But I got a problem for the LINQ order by sentence, it only works when I specify the actual field, but I need pass this field name as a parameter. so something like var expectedList = jObjList.OrderBy(x => x.parameterFieldName.ToString());
please give me some suggestions, many thanks.
public void VerifyOrderBy(string jsonString, string parameterFieldName)
{
List<dynamic> jObjList = JsonConvert.DeserializeObject<List<dynamic>>(jsonString);
var expectedList = jObjList.OrderBy(x => x.LastName.ToString());
Assert.IsTrue(expectedList.SequenceEqual(jObjList));
}
the JSON string looks like follows
[
{
"FirstName": "w3pCj",
"LastName": "mSJOV",
"IsDeleted": false
},
{
"FirstName": "rMnH7",
"LastName": "rMnH7",
"IsDeleted": false
},
{
"FirstName": "Jia",
"LastName": "Yu",
"IsDeleted": false
}
]
You can use the nameof()
operator keyword like this:
jObjList.OrderBy(x => nameof(x.LastName));
UPDATE #1
Let's say we have a Person
class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsDeleted { get; set; }
}
Let's say we have a list of people:
var people =
JsonConvert
.DeserializeObject<List<Person>>(
File.ReadAllText("data.json", Encoding.UTF8)
);
We can have a parameter that will contain the property name we want to order by:
string parameterName = nameof(Person.LastName); // or simply "LastName"
We get a reference to that property:
PropertyInfo orderByProperty =
typeof(Person)
.GetProperties()
.SingleOrDefault(property => property.Name == parameterName);
Now we can order by the selected property:
var result = people.OrderBy(person => orderByProperty.GetValue(person)).ToList();
Please note:
orderByProperty
is not null
. :) Do not forget to add the required using
statement to be able to get the PropertyInfo
:
using System.Reflection;
UPDATE #2
If you have such a simple json structure and you want to use dynamic
objects for ordering then you can achieve it like this:
var people =
JsonConvert
.DeserializeObject<List<dynamic>>(
File.ReadAllText("data.json", Encoding.UTF8)
);
string parameterName = "LastName";
var result =
people
.OrderBy(person =>
{
var personObject = person as JObject;
var propertyValueObject = personObject.GetValue(parameterName) as JValue;
return propertyValueObject.Value;
})
.ToList();
Although it works I would prefer UPDATE #1 solution. :)
Here is an implementation with custom comparer. This allows you to pass any property name:
public class JObjComp<T> : IComparer<T>
{
private string _field;
public JObjComp(string field)
{
_field = field;
}
int IComparer<T>.Compare(T a, T b)
{
//this is bit flimsy but as we know that passed object is
//a dynamic, should work
dynamic aa=(dynamic)a;
dynamic bb=(dynamic)b;
return string.Compare(aa[_field].ToString(), bb[_field].ToString());
}
}
Now use our custom comparer:
List<dynamic> jObjList = JsonConvert.DeserializeObject<List<dynamic>>(jstr);
jObjList.Sort(new JObjComp<dynamic>(field));
The list is sorted insitu, so you can assert using jObjList
itself.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.