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

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

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.

Send Correct Data Fetched to my Model via API

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

'there is no argument given that corresponds to required formal parameter'

I'm getting an error I can't seem to resolve.. I'm trying to fetch data from an API do a model and I'm getting an error which says:
'there is no argument given that corresponds to required formal parameter'
[HttpGet("basket/{identifier}")]
public async Task<OrderDTO> FetchBasket(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);
OrderDTO orderDTO = null;
if (!httpResponseMessage.IsSuccessStatusCode)
return orderDTO;
using var contentStream =
await httpResponseMessage.Content.ReadAsStreamAsync();
var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var orderServiceDtoExtract = await JsonSerializer.DeserializeAsync
<OrderLine>(contentStream, options);
orderDTO = new OrderLine // I'm getting the error here
{
ProductId = orderServiceDtoExtract.ProductId,
Quantity = orderServiceDtoExtract.Quantity
};
return orderDTO; // 200 OK
}
This is my model:
public class OrderLine
{
public OrderLine(int productId, int quantity)
{
ProductId = productId;
Quantity = quantity;
}
public int Id { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
}
When making an instance of the OrderLine type, you're using the Object Initializer syntax. However, because you explicitly made a Constructor with non-zero arguments, you must call that first.
orderDTO = new OrderLine(orderServiceDtoExtract.ProductId, orderServiceDtoExtract.Quantity);
Optionally, you can use the Object Initializer syntax after calling the constructor:
orderDTO = new OrderLine(orderServiceDtoExtract.ProductId, orderServiceDtoExtract.Quantity)
{
// set more properties...
};

Customize returning JSON from ASP.NET Core API , Values with Statuscode

I'm trying to return back JSON with customization , anyone can help to return the result like this :
{
status: 200,
message: "success",
data: {
var1: {
},
var2: {
}
}
}
with this code :
return Ok(new
{
var1,
var2
});
Why do you need to use the OkResult object?
A simple way of returning what you'd like is to use dynamic objets, or a class with properties matching the Json you'd like to get, and a JsonResult object.
dynamic json = new ExpandoObject();
json.Result = 200;
json.Message = "success";
json.Data.var1 = "whatever";
json.Data.var2 = "something else";
Response.StatusCode = json.Result; //matches the HTTP Status Code with the one from your json
return new JsonResult(json);
I used this for taking profile information from google id token , and then generate JWT token from my backend server and retuen back JWT and Profile info for client apps so this is the solution :
var profile = (new RetrnedUserProfile
{
Email = payload.Email,
FirstName = payload.GivenName,
FamilyName = payload.FamilyName,
PictureUrl = payload.Picture
});
return Ok(new ResponseModel
{
StatusCode = HttpStatusCode.OK,
Message = "success",
Data = new
{
profile,
accessToken
}
});
public class RetrnedUserProfile
{
public string FirstName { get; set; }
public string FamilyName { get; set; }
public string Email { get; set; }
public string PictureUrl { get; set; }
}
public class ResponseModel
{
public HttpStatusCode StatusCode { get; set; }
public string Message { get; set; }
public object Data { get; set; }
}

How can i get all values of JSON array

I have this JSON response:
{
"post_parameters_error_flag": false,
"data_error_flag": false,
"row_count": 7,
"message": "Operazione completata.",
"title": [
"title0",
"title1",
"title2",
"title3",
"title4",
"title5",
"title6"
],
"data": [
"value0",
"value1",
"value2",
"value3",
"value4",
"value5",
"value6",
"value7"
]
}
I need to write in a list (for example) all values obtained from 'data' array but I don't know how to get data from response:
string URL = "myurl";
string Params = string.Format("hwid={0}&building={1}", Utils.UUID(), "test");
Request HTTPRequest = new Request();
JObject JSONObject = JObject.Parse(await HTTPRequest.PostAsyncResponse(URL, Params));
//now? what can i do
Any idea to solve?
You can either use like this:
var result = await HTTPRequest.PostAsyncResponse(URL, Params)
var token = JToken.Parse(result);
var data= token.Value<JArray>("data");
Or you can also use JsonPath:
var result = await HTTPRequest.PostAsyncResponse(URL, Params)
var token = JToken.Parse(result);
var data = token.SelectTokens("$.data[*]");
But really, you should be serilizing into an object and then using the properties to get the data (or other properties):
public class RootObject
{
public bool post_parameters_error_flag { get; set; }
public bool data_error_flag { get; set; }
public int row_count { get; set; }
public string message { get; set; }
public List<string> title { get; set; }
public List<string> data { get; set; }
}
var result = await HTTPRequest.PostAsyncResponse(URL, Params)
var item = JsonConvert.DeserializeObject<RootObject>(result);
var data = item.data;
Try this,
var data = JObject.Parse(await HTTPRequest.PostAsyncResponse(URL, Params))["data"]
OR
var jsonObject = (JObject)JsonConvert.DeserializeObject(await HTTPRequest.PostAsyncResponse(URL, Params));
var data = (JObject)(jsonObject.Property("data").Value);

Categories

Resources