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
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);
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.
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);
}
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);
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.