Send Correct Data Fetched to my Model via API - c#

When I fetch data from my Basket API to further on post to my OrderLine API I get this back in JSON:
[
{
"productId": 1,
"quantity": 1
}
]
but my OrderLine API accepts the following:
{
"productId": 0,
"quantity": 0
}
I want to send the data fetched from my Basket API to my OrderLine so that the following is returned:
{
"orderID": 0,
"identifier": "string",
"customer": "string",
"items": [
{
"id": 0,
"productId": 0,
"quantity": 0
}
]
}
Where "items" is the data fetched from my Basket.
This is what my API GET Basket looks like for fetching data from basket:
// GET: https://localhost:5500/api/Basket/{identifier}
[HttpGet("/basket/{identifier}")]
public async Task<IEnumerable<OrderLineDTO>> GetBasketItems(string identifier)
{
var httpRequestMessage = new HttpRequestMessage(
HttpMethod.Get,
$"https://localhost:5500/api/Basket/{identifier}")
{
Headers = { { HeaderNames.Accept, "application/json" }, }
};
var httpClient = httpClientFactory.CreateClient();
using var httpResponseMessage =
await httpClient.SendAsync(httpRequestMessage);
var items = Enumerable.Empty<OrderLineDTO>();
if (!httpResponseMessage.IsSuccessStatusCode)
return items;
using var contentStream =
await httpResponseMessage.Content.ReadAsStreamAsync();
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var basketDto = await System.Text.Json.JsonSerializer.DeserializeAsync
<OrderDTO>(contentStream, options);
items = basketDto.Items.Select(x =>
new OrderLineDTO
{
ProductId = x.ProductId,
Quantity = x.Quantity,
}
);
var entryJson = new StringContent(
JsonSerializer.Serialize(items),
Encoding.UTF8,
Application.Json);
await httpClient.PostAsync($"http://localhost:5700/api/OrderLine", entryJson);
return items; // 200 OK
}
And this is my Post to OrderLine:
// POST: api/OrderLine
[HttpPost("/api/OrderLine")]
public async Task<ActionResult<Order>> PostOrderLine(OrderLine orderLine)
{
_context.OrderLine.Add(orderLine);
await _context.SaveChangesAsync();
return CreatedAtAction("GetOrder", new { id = orderLine.Id }, orderLine);
}
This is my OrderLineDTO:
public class OrderLineDTO
{
public int ProductId { get; set; }
public int Quantity { get; set; }
}
And this is my OrderLine model:
public class OrderLine
{
public int Id { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
}
Does anybody know how to solve this? Thanks in advance for any help, I'm just hoping to get the corresponding fetched data from my Basket API then send in back to OrderLine
EDIT:
Also added my OrderDTO which is callled upon in my GET Basket Method:
public class OrderDTO
{
public string Identifier { get; set; }
public string Customer { get; set; }
public List<OrderLine> Items { get; set; } = new List<OrderLine>();
}

You are returning items which is an object of type OrderLineDTO
What you want to return is an object of type OrderDTO

Related

JSON can not be deserialized

I have made an API request which fetches data from an API. When I look at the JSON I get, it contains the data I need. However, when I try to deserialize the JSON, it does not work.
JSON:
{
"get":"leagues",
"parameters":[
],
"errors":[
],
"results":960,
"paging":{
"current":1,
"total":1
},
"response":[
{
"league":{
"id":4,
"name":"Euro Championship",
"type":"Cup",
"logo":"https:\/\/media-3.api-sports.io\/football\/leagues\/4.png"
},
"country":{
"name":"World",
"code":null,
"flag":null
},
"seasons":[
{
"year":2008,
"start":"2008-06-07",
"end":"2008-06-29",
"current":false,
"coverage":{
"fixtures":{
"events":true,
"lineups":true,
"statistics_fixtures":false,
"statistics_players":false
},
"standings":false,
"players":false,
"top_scorers":false,
"top_assists":false,
"top_cards":false,
"injuries":false,
"predictions":true,
"odds":false
}
},
{
"year":2012,
"start":"2012-06-08",
"end":"2012-07-01",
"current":false,
"coverage":{
"fixtures":{
"events":true,
"lineups":true,
"statistics_fixtures":false,
"statistics_players":false
},
"standings":false,
"players":false,
"top_scorers":false,
"top_assists":false,
"top_cards":false,
"injuries":false,
"predictions":true,
"odds":false
}
},
{
"year":2016,
"start":"2016-06-10",
"end":"2016-07-10",
"current":false,
"coverage":{
"fixtures":{
"events":true,
"lineups":true,
"statistics_fixtures":true,
"statistics_players":true
},
"standings":true,
"players":false,
"top_scorers":false,
"top_assists":false,
"top_cards":false,
"injuries":false,
"predictions":true,
"odds":false
}
},
{
"year":2020,
"start":"2019-03-21",
"end":"2021-07-11",
"current":true,
"coverage":{
"fixtures":{
"events":true,
"lineups":true,
"statistics_fixtures":true,
"statistics_players":true
},
"standings":true,
"players":true,
"top_scorers":true,
"top_assists":true,
"top_cards":true,
"injuries":false,
"predictions":true,
"odds":false
}
}
]
},
Request:
public class LeagueService : ILeagueService
{
public async Task GetLeaguesFromApiAsync()
{
var client = new HttpClient();
var request = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri("-"),
Headers =
{
{ "X-RapidAPI-Key", "-" },
{ "X-RapidAPI-Host", "-" },
}};
using var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
var body = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<Root>(body);
}
}
Root class:
public class Root
{
public string Get { get; set; }
public List<object> Parameters { get; set; }
public List<object> Errors { get; set; }
public int Results { get; set; }
public Paging Paging { get; set; }
public List<Response> Response { get; set; }
}
I have checked if the API returns values and it does. However, after deserialization all values in the result are null.

JSON convert array type to list in C#

I have some array data coming from an API in JSON format, and I want to convert an array type to a list. There is an ASP.NET MVC project and I used the list in Index page. How can I deserialize the array format into a list?
Controller
public async Task<IActionResult> ListCountries()
{
List<Country> countries = new List<Country>();
HttpClient _client = new HttpClient();
HttpResponseMessage _response = new HttpResponseMessage();
_client = _apiHelper.Initial();
_response = await _client.GetAsync("api/Countries/getall");
if (_response.IsSuccessStatusCode)
{
var results = _response.Content.ReadAsStringAsync().Result;
countries = JsonConvert.DeserializeObject<List<Country>>(results);
}
return View(countries);
}
Data
"data": [
{
"id": 1,
"countryName": "Afghanistan"
},
{
"id": 2,
"countryName": "Albania"
},
{
"id": 3,
"countryName": "Algeria"
},
Entity
public class Country
{
[Key]
public int Id { get; set; }
public string CountryName { get; set; }
}
Your json data is invalid format. Json maybe have to be like this:
{
"data": [
{
"id": 1,
"countryName": "Afghanistan"
},
{
"id": 2,
"countryName": "Albania"
},
{
"id": 3,
"countryName": "Algeria"
}
]
}
After that you should create 2 c# class like this:
public class JsonData
{
public List<Country> data { get; set; }
}
public class Country
{
public int id { get; set; }
public string countryName { get; set; }
}
Then you can deserialize it without any error.
public async Task<IActionResult> ListCountries()
{
List<Country> countries = new List<Country>();
HttpClient _client = new HttpClient();
HttpResponseMessage _response = new HttpResponseMessage();
_client = _apiHelper.Initial();
_response = await _client.GetAsync("api/Countries/getall");
if (_response.IsSuccessStatusCode)
{
var results = _response.Content.ReadAsStringAsync().Result;
countries = JsonConvert.DeserializeObject<JsonData>(results);
}
return View(countries);
}
The object has a variable data that contains the countries whereas the class you're trying to serialize to does not.
Having a class such as:
public class Country{
[JsonProperty('data')]
public List<data> Details {get;set;}
public Country(){
Details = new List<data>();
}
public class data{
[Key]
[JsonProperty('id')]
public int Id { get; set; }
[JsonProperty('countryName')]
public string CountryName { get; set; }
}
and then to deserialize it you would need:
countries = JsonConvert.DeserializeObject<Country>(results);
When it deserializes the object it will map data to the Details variable in the class Country and map each value in the response array to the data class
The structure shown is not a list/array of Countries but an object which has a property data which is a list/array of Contries:
public class Result
{
public List<Country> Data {get; set;}
}
...
var r = JsonConvert.DeserializeObject<Result>(results);
var countries = r.Data;
Minor note. Since you're using Json.NET it's OK that your properties don't match the case in json, but if you switch to System.Text.Json this would become an issue.
you have to parse and use JArray inside of your result
var countries = JObject.Parse(results)["data"].ToObject<List<Country>>();
// data for test
var results = #"{""data"": [
{
""id"": 1,
""countryName"": ""Afghanistan""
},
{
""id"": 2,
""countryName"": ""Albania""
},
{
""id"": 3,
""countryName"": ""Algeria""
}]}";

System.ArgumentNullException: Value cannot be null. (Parameter 'factory')

I'm getting an error in PostMan fetching data from my API:
System.ArgumentNullException: Value cannot be null. (Parameter 'factory')
This is my controller:
[HttpGet("basket/{identifier}")]
public async Task<IEnumerable<NewBasketDTO.ItemDTO>> FetchBasketEntries(string identifier)
{
var httpRequestMessage = new HttpRequestMessage(
HttpMethod.Get,
$"https://localhost:5500/api/Basket/{identifier}")
{
Headers = { { HeaderNames.Accept, "application/json" }, }
};
var httpClient = httpClientFactory.CreateClient();
using var httpResponseMessage =
await httpClient.SendAsync(httpRequestMessage);
var basketEntires = Enumerable.Empty<NewBasketDTO.ItemDTO>();
if (!httpResponseMessage.IsSuccessStatusCode)
return basketEntires;
using var contentStream =
await httpResponseMessage.Content.ReadAsStreamAsync();
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var basketDTO = await JsonSerializer.DeserializeAsync
<DTO.NewBasketDTO.ItemDTO>(contentStream, options);
basketDTO = new NewBasketDTO.ItemDTO
{
ProductId = basketDTO.ProductId,
Quantity = basketDTO.Quantity
};
return basketEntires; // 200 OK
}
Here is my model DTO:
public class NewBasketDTO
{
public class ItemDTO
{
public int ProductId { get; set; }
public int Quantity { get; set; }
}
[ActivatorUtilitiesConstructor]
public class BasketDTO
{
public string Identifier { get; set; }
public List<ItemDTO> Items { get; set; }
}
}
I'm trying to get this data here from my API:
[
{
"productId": 0,
"quantity": 0
}
]
What am I doing wrong? I'm trying to fetch data from my API with Http in my controller and I want that data to be added to my NewBasketDTO and returned in JSON format so that I can post it to another database later on but I can't even seem to get it correctly without it giving me this error of value cannot be null

Mongodb C# Update element in an multiple array with multiple values

I want to update the single document in collection with the guid as filter and update value is cityType. Every guid has different citytype here i have used 3 types it may be more.
So please give a right implementation using c# code.
Models:
public class Country
{
[BsonId]
public ObjectId Id { get; set; }
public int CountryId {get; set; }
public IEnumerable<States> States { get; set; }
}
public class States
{
public Guid Guid { get; set; }
public CityType CityType { get; set; }
}
Enum CityType
{
Unknown = 0,
Rural = 1,
Urban = 2
}
Existing Collection:
{
"_id": ObjectId("6903ea4d2df0c5659334e763"),
"CountryId": 200,
"States": [
{
"Guid": "AFCC4BE7-7585-5E46-A639-52F0537895D8",
"CityType": 0,
},
{
"Guid": "208FB603-08C7-46D9-B0C0-7AF4F691A96D",
"CityType": 0,
}
}
Input:
List<States>()
{
new States()
{
Guid = "AFCC4BE7-7585-5E46-A639-52F0537895D8",
CityType = CityType.Rural
},
new States()
{
Guid = "208FB603-08C7-46D9-B0C0-7AF4F691A96D",
CityType = CityType.Urban
}
}
Expected:
{
"_id": ObjectId("6903ea4d2df0c5659334e763"),
"CountryId": 200,
"States": [
{
"Guid": "AFCC4BE7-7585-5E46-A639-52F0537895D8",
"CityType": 1,
},
{
"Guid": "208FB603-08C7-46D9-B0C0-7AF4F691A96D",
"CityType": 2,
}
}
This is the method I have tried:
public async Task<bool> UpdateType(int countryId, IEnumerable<States> states)
{
var collection = connectionFactory.GetCollection<Country>(collectionName);
var cityTypes = states.Select(x => x.CityType);
var filter = Builders<Country>.Filter.Empty;
var update = Builders<Country>.Update.Set("States.$[edit].CityType", cityTypes);
var arrayFilters = new List<ArrayFilterDefinition>();
foreach (var state in states)
{
ArrayFilterDefinition<Country> optionsFilter = new BsonDocument("state.Guid", new BsonDocument("$eq", state.Guid));
arrayFilters.Add(optionsFilter);
}
var updateOptions = new UpdateOptions { ArrayFilters = arrayFilters };
var result = await collection.UpdateOneAsync(filter, update, updateOptions);
return result;
}
hope all details I have added here. Thanks in advance.
You don't have to loop through it:
Let's say you have a Class1 like this:
class Question : AuditableEntity {
public string Text { get; set; }
public List<string> Tags { get; set; } = new List<string>();
so you just say:
await collection.UpdateOneAsync(
someFilter,
Builders<Class1>.Update
.Set(f => f.Text, request.Question.Text)
.Set(f => f.Tags, request.Question.Tags));

Writing JSON array in web API response

Need a JSON response like this:
{
"statusCode": 200,
"errorMessage": "Success",
"Employees": [
{
"empid": "7228",
"name": "Tim",
"address": "10815 BALTIMORE",
},
{
"empid": "7240",
"name": "Joe",
"address": "10819 Manasas",
}
]
}
Model Class:
public class EmployeeList
{
public string empid { get; set; }
public string name { get; set; }
public string address { get; set; }
}
public class Employee
{
public int statusCode { get; set; }
public string errorMessage{ get; set; }
public List<EmployeeList> Employees { get; set; }
}
Controller is like this:
List<Models.Employee> emp = new List<Models.Employee>();
//call to SP
if (rdr.HasRows)
{
var okresp = new HttpResponseMessage(HttpStatusCode.OK)
{
ReasonPhrase = "Success"
};
Models.Employee item = new Models.Employee();
{
item.statusCode = Convert.ToInt32(okresp.StatusCode);
item.errorMessage = okresp.ReasonPhrase;
while (rdr.Read())
{
item.Employees = new List<EmployeeList>{
new EmployeeList
{
empid = Convert.ToString(rdr["empid"]),
name = Convert.ToString(rdr["name"]),
address = Convert.ToString(rdr["address"])
}};
}
};
emp.add(item);
// return response
What should be my controller class code to create JSON array response while I read data from reader?
I am not able to get the loop part of creating JSON array in response file. Am I assigning the values in While loop incorrectly?
After your while (rdr.Read()), you reset item.Employees with a new List<EmployeeList> at every data. So you will be getting the last element every time.
Move your list initialisation outside of the loop and use the add method.
item.Employees = new List<EmployeeList>();
while (rdr.Read())
{
item.Employees.Add(
new EmployeeList
{
empid = Convert.ToString(rdr["empid"]),
name = Convert.ToString(rdr["name"]),
address = Convert.ToString(rdr["address"])
});
}

Categories

Resources