Filtering JSON based on value - c#

I have this object and would like to filter it based on the value of customer_email. For example, I only want to return commissions where the customer email is test#test.com. This is a simplified example of what a response would look like. Below is the method where I grab all the data.
public RootObject GetData(string customerEmail)
{
var data = new Commission();
using (var httpClient = new HttpClient())
{
var requestContent = JObject.FromObject(new
{
commission_id = data.id,
customer_email = customerEmail
}).ToString();
......
RootObject response = JsonConvert.DeserializeObject<RootObject>(responseContent);
return response;
}
}
When I get the response, the information looks like this:
{"response":{
"code":"200",
"message":"OK: The request was successful. See response body for additional data.",
"data":{
"commissions":
[{
"commission_id":"12345",
"customer_email":"test#test.com"
},
{
"commission_id":"67890",
"customer_email":"fake#fake.com"
}]

You can achieve it using simple LINQ right after serialization of response to RootObject.
return response
.Response.Data.Commissions
.Where(commission => commission.CustomerEmail == customerEmail);

Then you can use a lambda expression to easily filter the contents of that list.
return response.Response.Data.Commissions.Where(c => c.customerEmail==customerEmail);
This will return only the instances of Commission in the response's commissions collection.
A side effect of this solution would be changing the return type of the method from RootObject to IEnumerable<Commission>. Which would mean that callers of this method would no longer have access to any other data in the response object (besides the commissions data).

Related

How to deserialize dynamic Json objects?

I am currently receiving the following JSON response from my api:
{"Lastname":["ERRLASTNAMEEMPTY"],"Firstname":["ERRFIRSTNAMEEMPTY"]}
Note that the above response is dynamic - i.e sometimes I can have FirstName, sometimes LastName, sometimes both. This response is based on the validation of data.
My question is - is there a way to deserialize this response using JsonSerializer.DeSerialize?
I have tried to use it like this but it does not work:
var errorBody = JsonSerializer.Deserialize<dynamic>(body, serializerOptions);
JsonSerializer.Deserialize<Dictionary<string,string[]>>(body, serializerOptions);
You can work with dynamic JSON objects with JObject like that:
var data = JObject.Parse(body);
And later you are able to access values with data["Lastname"]?.Value<string>(); and such, the way you want.
JsonSerializer.Deserialize<ExpandoObject>(body, serializerOptions);
// introduce a dynamic object from a string :
// {"UrlCheckId":581,"Request":{"JobId":"a531775f-be19-4c78-9717-94aa051f6b23","AuditId":"b05016f5-51c9-48ba-abcc-ec16251439e5","AlertDefinitionId":108,"JobCreated":"2022-05-20T07:09:56.236656+01:00","UrlJobId":0,"BatchJobId":"e46b9454-2f90-407d-9243-c0647cf6502d"},"JobCreated":"2022-05-20T07:10:21.4097268+01:00"}
// ...The UrlCheckId is an int primitive and Request is our UrlCheckJobRequest object.
dynamic msg = JsonConvert.DeserializeObject(message);
// to access an int (primitive) property:
int id = msg.UrlCheckId;
// to access an object, you might have to serialize the request into a string first...
var r = JsonConvert.SerializeObject(msg.Request);
// ... and then deserialize into an object
UrlCheckJobRequest request = JsonConvert.DeserializeObject<UrlCheckJobRequest>(r);

Newtonsoft.Json.Linq.JArray.Parse(string)' has some invalid arguments

I am trying to extract data from D2L for the dropbox submissions using API's I have a link which returns a Json Array as per told on the documentation and from this Array I just need the Id feild nothing else.
I have tried to convert this Array into dynamic Object but that didn't help.
Here is my code.
var client = new RestClient("https://" + LMS_URL);
var authenticator = new ValenceAuthenticator(userContext);
string Link = "/d2l/api/le/1.12/UnitID/dropbox/folders/UniID/submissions/";
var request = new RestRequest(string.Format(Link));
request.Method = Method.GET;
authenticator.Authenticate(client, request);
var response = client.Execute(request);
string jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(response.Content);
Response.Write(jsonString);
//var splashInfo = JsonConvert.DeserializeObject<ObjectD>(response.Content);
dynamic jsonResponse = JsonConvert.DeserializeObject(response.Content);
var parsedObject = jsonResponse.Parse(jsonResponse);
string json = jsonResponse;
var popupJson = parsedObject["id"].ToString();
What my goal is that grab the list of ID's from this response and loop through them, these ID's are the key for my next API route.
Here is a glance at what I get from the response:
[
{
"Id": 2021,
"CategoryId": null,
"Name": "Graded Assignment: Part 1",
"CustomInstructions": {
"Text": "Directions:\r\nCOMPLETE the following TestOut Activities\r\n\r\n1.2.10 Practice Questions\r\n1.3.8 Practice Questions\r\n\r\nGo to TestOut to complete the Assignment."
//Other properties omitted
}
//Other properties omitted
}
]
The outermost container in the JSON returned is an array, so you need to deserialize to a collection type as specified in the Newtonsoft's Serialization Guide: IEnumerable, Lists, and Arrays.
Since you only care about the Id property of the object(s) in the array, you can use JsonConvert.DeserializeAnonymousType to deserialize just the interesting value(s):
var ids = JsonConvert.DeserializeAnonymousType(response.Content, new [] { new { Id = default(long) } })
.Select(o => o.Id)
.ToList();
And if you are certain the outermost array will contain exactly one item, you can do:
var id = JsonConvert.DeserializeAnonymousType(response.Content, new [] { new { Id = default(long) } })
.Select(o => o.Id)
.Single();
Alternatively, if you think you will later need to deserialize additional properties, you could make an explicit data model as follows:
public class ObjectId
{
public long Id { get; set; }
}
And do:
var ids = JsonConvert.DeserializeObject<List<ObjectId>>(response.Content)
.Select(o => o.Id)
.ToList();
Notes:
You will need to determine from the API documentation whether long or int is more appropriate for the Id value.
As a general rule I recommend not parsing to dynamic because you lose compile-time checking for correctness. When dealing with completely free-form JSON, parsing to JToken may be a better solution -- but your JSON appears to have a fixed schema, so neither is necessary.
Demo fiddle here.

Get only users with TransitiveMembers Microsoft Graph C# SDK

I want to get all users that are member of a group (transitive).
This call gets what I want:
https://graph.microsoft.com/v1.0/groups/{guid}/transitiveMembers/microsoft.graph.user
In my C# application I use the Graph API SDK. I know how you specify queryoptions, but I need an url segment instead of a query options.
At the moment I have this:
graphClient.Groups[guid].TransitiveMembers.Request().Select("id").GetAsync();
This returns all members, but not only users. So if someone know how to achieve this with the C# sdk please let me know.
The provided request:
GET https://graph.microsoft.com/v1.0/groups/{group-id}/transitiveMembers/microsoft.graph.user
could be constructed and executed via msgraph-sdk-dotnet like this:
var requestUrl = $"{graphClient.Groups[groupId].TransitiveMembers.Request().RequestUrl}/microsoft.graph.user";
var message = new HttpRequestMessage(HttpMethod.Get, requestUrl);
await graphClient.AuthenticationProvider.AuthenticateRequestAsync(message);
var response = await graphClient.HttpProvider.SendAsync(message);
and the response de-serialized like this:
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
var json = JObject.Parse(content);
var items = json["value"].Where(i => (string)i["#odata.type"] == null);
var members = items.Select(item => item.ToObject<Microsoft.Graph.User>());
foreach (var member in members)
{
Console.WriteLine(member.UserPrincipalName);
}
}
Since the query /groups/{group-id}/transitiveMembers/microsoft.graph.user still returns the collection of all transitive members but only the properties for microsoft.graph.user object are retrieved meaning it is not working precisely the same way as $filter parameter, maybe a more straightforward way would be:
a) retrieve all the transitive members via request:
var members = await graphClient.Groups[groupId].TransitiveMembers.Request().GetAsync();
b) and filter by user type:
var userMembers = members.Where(m => m.ODataType == "#microsoft.graph.user").Cast<User>();
foreach (var member in userMembers)
{
Console.WriteLine(member.UserPrincipalName);
}

Angular not parsing JSON into object

Can someone explain why my JSON object isnt being correctly parsed into an Angular object? (the Angular object values are empty when I display HTML)
Angular code making request for JSON
GetMessageSub(): void {
this.http.get('http://localhost:61460/api/values')
.pipe(map(res => JSON.parse(res.toString())),
catchError(this.handleError('getMessageSub()', [])))
.subscribe(people => this.people = people);
}
C# code that is replying with a JSON
public JsonResult Get()
{
return Json("[{ id:1, name:\"value2\" }]");
}
Angular code that declares a People object
export class People {
id: number;
name: string;
}
HTML that calls the people object (which is populated by GetMessageSub()
people found: {{people.id}} -- {{people.name}}
Your C# code:
return Json("[{ id:1, name:\"value2\" }]");
returns a string, "[{ id:1, name:\"value2\" }]", encoded as JSON, so "\"[{ id:1, name:\\\"value2\\\" }]\"", not an array with a single object. If you want to do that, either:
Build an array of objects in C# and send that through JSON:
return Json(new object[] { new { id = 1, name = "value2" } });
Or send it as a string using a ContentResult:
return Content("[{ id:1, name:\"value2\" }]", "application/json");
You'd need to change the signature of your method as well for the latter option.
You are already returning a valid JSON, no need to parse, just assign
this.http.get('http://localhost:61460/api/values')
.pipe(map(res =>res)),
catchError(this.handleError('getMessageSub()', [])))
.subscribe(people => this.people = people);

Getting empty array while ajax query to MVC controller

I am using $.ajax method to get the data from the MVC controller. I am usingPOST method according to the JSON Hijacking for security standards. If I debug I am able to get the data in controller, but after returning data to the $.ajax's success function then it is showing me empty json array like below.
In controller I am using method as below:
public async Task<ActionResult> GetUsersFromOrganization(string searchString) {
string accessToken = await SampleAuthProvider.Instance.GetUserAccessTokenAsync();
var result = await graphService.GetUsersFromOrg(accessToken, searchString);
var json = JObject.Parse(result);
var valueJSON = json.GetValue("value");
return Json(valueJSON, JsonRequestBehavior.AllowGet);
}
json contains below data:
Here is the valueJSON value
The valueJSON is a JToken, Json(valueJSON) method is serializing your valueJson as a JToken class and not as the deserialized array of objects that you need, you can try to return the JToken as a string with return Content(valueJSON .ToString(),"application/json"); or parse the JToken to the original array of objects.

Categories

Resources