System.Text.Json.JsonException - Error deserializing - asp.net-core

Here is my code:
public class Element
{
public string? Group { get; set; }
public int Position { get; set; }
public string? Name { get; set; }
public int Number { get; set; }
[JsonPropertyName("small")]
public string? Sign { get; set; }
public double Molar { get; set; }
public IList<int>? Electrons { get; set; }
public override string ToString()
{
return $"{Sign} - {Name}";
}
}
public List<Element> LoadJson()
{
using (StreamReader r = new StreamReader("jsondata/elements.json"))
{
string json = r.ReadToEnd();
var ElementObject = JsonSerializer.Deserialize<List<Element>>(json);
return ElementObject;
}
}
elements.json
{
"elements": [
{
"group": "Other",
"position": 0,
"name": "Hydrogen",
"number": 1,
"small": "H",
"molar": 1.00794,
"electrons": [
1
]
},
{
"group": "Noble Gas (p)",
"position": 17,
"name": "Helium",
"number": 2,
"small": "He",
"molar": 4.002602,
"electrons": [
2
]
}
]
}
while I am trying to deserialize I get
System.Text.Json.JsonException: 'The JSON value could not be converted to System.Collections.Generic.List`1[BlazorApp4.Shared.Entities.Element]. Path: $ | LineNumber: 0 |
What am I missing?

The JSON doesn't represent a List<Element>. It represents an object which has a property which is a List<Element>.
Create that object:
public class Root
{
public List<Element> Elements { get; set; }
}
And deserialize into that:
var root = JsonSerializer.Deserialize<Root>(json);
return root.Elements;

Related

How to define the name of the data for the ajax.datatable column name? I keep getting the unknow parameter error for ajax.datatable

JobProg.js
var dataTable;
$(document).ready(function () {
loadDataTable();
});
function loadDataTable() {
dataTable = $('#tblData').DataTable({
"ajax": {
"url": "/Admin/CMJobProg/GetAll"
},
"columns": [
{ "data": "jobnumber", "width": "35%" },
{ "data": "assignfrom", "width": "35%" },
{ "data": "assignto", "width": "35%" },
{ "data": "dateassign", "width": "35%" },
{ "data": "jobaction", "width": "35%" },
{ "data": "remarks", "width": "35%" },
{ "data": "type", "width": "35%" },
{ "data": "division" ,"width": "35%" }
]
})
}
CMJobProg.cs
namespace LXG.Models
{
[Table("CMJOBPROG", Schema = "LASIS")]
public class CMJobProg
{
[Required]
[MaxLength(8)]
[Display(Name = "Job Number")]
[Column("JOB_NUMBER")]
public string JobNumber { get; set; }
[Display(Name = "Assign From")]
[MaxLength(22)]
[Column("ASSIGN_FROM")]
public string AssignFrom { get; set; }
[Display(Name = "Assign To")]
[MaxLength(22)]
[Column("ASSIGN_TO")]
public string AssignTo { get; set; }
[Column("DATE_ASSIGN")]
public DateTime DateAssign { get; set; }
[Display(Name = "Job Action")]
[Range(0, 999)]
[Column("JOB_ACTION")]
public int? JobAction { get; set; }
[Display(Name = "Remarks")]
[MaxLength(500)]
[Column("REMARKS")]
public string Remarks { get; set; }
[Display(Name = "Job Type")]
[Required]
[MaxLength(2)]
[Column("TYPE")]
public string Type { get; set; }
[MaxLength(2)]
[Column("DIVISION")]
public string Division { get; set; }
}
}
DataTables warning: table id=tblData - Requested unknown parameter 'jobnumber' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
I keep getting this error, how to fix this? I able to get the data remarks, type and division, but i cant get others data. Acutally how to define the name for the data name?
As far as I know, asp.net core returned json will has a special format. Like this : JobNumber to jobNumber. To solve this issue. I suggest you could set a JsonPropertyName attribute for each model property.
More details, you could refer to below codes:
[Table("CMJOBPROG", Schema = "LASIS")]
public class CMJobProgress
{
[Required]
[MaxLength(8)]
[Display(Name = "Job Number")]
[Column("JOB_NUMBER")]
[JsonPropertyName("jobnumber")]
public string JobNumber { get; set; }
[Display(Name = "Assign From")]
[MaxLength(22)]
[Column("ASSIGN_FROM")]
[JsonPropertyName("assignfrom")]
public string AssignFrom { get; set; }
[Display(Name = "Assign To")]
[MaxLength(22)]
[Column("ASSIGN_TO")]
[JsonPropertyName("assignto")]
public string AssignTo { get; set; }
[Column("DATE_ASSIGN")]
[JsonPropertyName("dateassign")]
public DateTime DateAssign { get; set; }
[Display(Name = "Job Action")]
[Range(0, 999)]
[Column("JOB_ACTION")]
[JsonPropertyName("jobaction")]
public string JobAction { get; set; }
[Display(Name = "Remarks")]
[MaxLength(500)]
[Column("REMARKS")]
[JsonPropertyName("remarks")]
public string Remarks { get; set; }
[Display(Name = "Job Type")]
[Required]
[MaxLength(2)]
[Column("TYPE")]
[JsonPropertyName("type")]
public string Type { get; set; }
[MaxLength(2)]
[Column("DIVISION")]
[JsonPropertyName("division")]
public string Division { get; set; }
}
Result:
Follow case-sensitive column name in your model/entity class. For example,
"data": "jobnumber"
to
"data": "JobNumber"
Add this "AddNewtonsoftJson" in Startup.cs
services.AddControllersWithViews().AddRazorRuntimeCompilation().AddNewtonsoftJson(options =>
{
options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});

Cannot deserialize the current JSON object Cannot deserialize the current JSON object with group column

I am calling the API and trying to store the Jsonresult into a IEnumerable model class. The json result has group header column consolidated_weather.
when I run the program the following error is coming
JsonSerializationException: Cannot deserialize the current JSON object into type 'System.Collections.Generic.IEnumerable`.
How can I call the given json result into the IEnumerable model class after avoiding group header from json result.
I am using the following two model.
public class Weather
{
[Key]
public long id { get; set; }
public string weather_state_name { get; set; }
public string weather_state_abbr { get; set; }
public string wind_direction_compass { get; set; }
public DateTime created { get; set; }
public DateTime applicable_date { get; set; }
public decimal min_temp { get; set; }
public decimal max_temp { get; set; }
public decimal the_temp { get; set; }
public double wind_speed { get; set; }
public decimal wind_direction { get; set; }
public decimal air_pressure { get; set; }
public decimal Humidity { get; set; }
public string Visibllity { get; set; }
public decimal Predictability { get; set; }
}
public class WeatherList
{
public IEnumerable<Weather> consolidated_weather { get; set; }
}
public async Task<IEnumerable<Weather>> GetWeatherAsync(string woied)
{
var url = SD.APIBaseUrl + woied;
var request = new HttpRequestMessage(HttpMethod.Get, url);
var client = _clientFactory.CreateClient();
HttpResponseMessage response = await client.SendAsync(request);
IEnumerable<Weather> weather = new List<Weather>();
WeatherList weatherList = new WeatherList();
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
var jsonString = await response.Content.ReadAsStringAsync();
weatherList = JsonConvert.DeserializeObject<WeatherList>(jsonString);
return weatherList;
}
return null;
}
The API result is coming as
<!-- language: lang-html -->
{
"consolidated_weather": [
{
"id": 4577625064341504,
"weather_state_name": "Heavy Rain",
"weather_state_abbr": "hr",
"wind_direction_compass": "WSW",
"created": "2020-07-14T19:35:14.577740Z",
"applicable_date": "2020-07-14",
"min_temp": 11.11,
"max_temp": 15.05,
"the_temp": 14.32,
"wind_speed": 6.570953330777592,
"wind_direction": 254.13274105640758,
"air_pressure": 1016.5,
"humidity": 85,
"visibility": 7.654361031575599,
"predictability": 77
},
{
"id": 4896540210495488,
"weather_state_name": "Showers",
"weather_state_abbr": "s",
"wind_direction_compass": "WNW",
"created": "2020-07-14T19:35:17.569534Z",
"applicable_date": "2020-07-15",
"min_temp": 12.31,
"max_temp": 17.03,
"the_temp": 16.509999999999998,
"wind_speed": 7.600821124862802,
"wind_direction": 284.49357944800784,
"air_pressure": 1015.5,
"humidity": 82,
"visibility": 13.558008729022509,
"predictability": 73
},
]
"title": "Texas",
"location_type": "City",
"timezone": "US"
<!-- end snippet -->
From your json string, we can see that there is a list of weather object in object consolidated_weather.
So you need to parse json to WeatherList.
public class WeatherList {
public IEnumerable<Weather> consolidated_weather { get; set; }
}
[HttpPost("/weather")]
public async Task<IEnumerable<Weather>> GetWeatherAsync()
{
string jsonString = "{\"consolidated_weather\":[{\"id\":4577625064341504,\"weather_state_name\":\"Heavy Rain\",\"weather_state_abbr\":\"hr\",\"wind_direction_compass\":\"WSW\",\"created\":\"2020-07-14T19:35:14.577740Z\",\"applicable_date\":\"2020-07-14\",\"min_temp\":11.11,\"max_temp\":15.05,\"the_temp\":14.32,\"wind_speed\":6.570953330777592,\"wind_direction\":254.13274105640758,\"air_pressure\":1016.5,\"humidity\":85,\"visibility\":7.654361031575599,\"predictability\":77},{\"id\":4896540210495488,\"weather_state_name\":\"Showers\",\"weather_state_abbr\":\"s\",\"wind_direction_compass\":\"WNW\",\"created\":\"2020-07-14T19:35:17.569534Z\",\"applicable_date\":\"2020-07-15\",\"min_temp\":12.31,\"max_temp\":17.03,\"the_temp\":16.509999999999998,\"wind_speed\":7.600821124862802,\"wind_direction\":284.49357944800784,\"air_pressure\":1015.5,\"humidity\":82,\"visibility\":13.558008729022509,\"predictability\":73}]}";
IEnumerable<Weather> weather = new List<Weather>();
WeatherList weatherList = new WeatherList();
weatherList = JsonConvert.DeserializeObject<WeatherList>(jsonString);
return weatherList.consolidated_weather;
}
Test Result
UPDATE
public class WeatherList
{
public IEnumerable<Weather> consolidated_weather { get; set; }
public string title { get; set; }
public string location_type { get; set; }
public string timezone { get; set; }
}
There are two missings in your json string:
<!-- language: lang-html -->
{
"consolidated_weather": [
{
"id": 4577625064341504,
...
},
{
"id": 4896540210495488,
...
},
] <!-- missing , -->
"title": "Texas",
"location_type": "City",
"timezone": "US"
<!-- missing } -->
<!-- end snippet -->
Assuming that you cannot change the content of the Json, you can create a ConsolidatedWeather class that contains the List of Weathers
public class ConsolidatedWeather
{
public List<Weather> Consolidated_Weather { get; set; }
}
and in your deserialize part
return JsonConvert.DeserializeObject<ConsolidatedWeather>(jsonString).Consolidated_Weather;

How to display Swashbuckle parameter object only with fields that should actually be sent?

I'm starting to work with Swagger using the Swashbuckle library for AspNetCore.
And when putting in my API an object with references it presents as if it were necessary to send all the fields of the references, when only the identifier (Id)
Here's an example:
Model Structure:
public class Cidade
{
public long Id { get; set; }
public string Nome { get; set; }
public Uf Uf { get; set; }
}
public class Uf
{
public long Id { get; set; }
public string Nome { get; set; }
public Pais Pais { get; set; }
}
public class Pais
{
public long Id { get; set; }
public string Nome { get; set; }
}
And the following API:
[Produces("application/json")]
[Route("api/Cidade")]
public class CidadeController : Controller
{
// POST: api/Cidade
[HttpPost]
public void Post([FromBody]Cidade value)
{
}
}
The result in Swagger is as follows:
And what I would like is the following (only up to uf.id):
How can I get this result?
I followed the logic of #HelderSepu answer, to get my solution, which would be as follows:
I built a Schema filter to add an example to the reference properties (Ref), which has a property called "Id":
public class ApplySchemaRefIdExtensions : ISchemaFilter
{
public void Apply(Schema schema, SchemaFilterContext context)
{
if (schema.Properties != null)
{
foreach (var p in schema.Properties)
{
if (p.Value.Example == null && p.Value.Ref != null)
{
var reference = context.SystemType.GetProperty(p.Value.Ref.Split("/").LastOrDefault());
if (reference != null)
{
var id = reference.PropertyType.GetProperty("Id");
if (id != null)
{
p.Value.Example = new
{
Id = 123
};
p.Value.Ref = null;
}
}
}
}
}
}
}
On Startup.cs:
services.AddSwaggerGen(c =>
{
// ...
c.SchemaFilter<ApplySchemaRefIdExtensions>();
});
Result for the same example of the question:
I was looking on my samples and I think I found something you can use:
http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=P#/PolygonVolume/PolygonVolume_Post
On my case I'm adding more, you need less, but still what you need is just a custom example...
the JSON looks like this:
"PolygonVolumeInsideParameter": {
"properties": {
"Points": {
"items": {
"$ref": "#/definitions/Location"
},
"xml": {
"name": "Location",
"wrapped": true
},
"example": [
{
"Lat": 1.0,
"Lon": 2.0
},
{
"Lat": 5.0,
"Lon": 6.0
}
],
"type": "array"
},
"PlanId": {
"type": "string"
}
},
"xml": {
"name": "PolygonVolumeInsideParameter"
},
"type": "object"
},
And on swashbuckle I added the example it with an ISchemaFilter my code is here:
https://github.com/heldersepu/Swagger-Net-Test/blob/master/Swagger_Test/App_Start/SwaggerConfig.cs#L891

ASP.NET core POST request fail

I have a model:
public class CoreGoal
{
[Key]
public long CoreGoalId { get; set; }
public string Title { get; set; }
public string Effect { get; set; }
public string Target_Audience { get; set; }
public string Infrastructure { get; set; }
public virtual ICollection<Benefit> Benefits { get; set; }
public virtual ICollection<Step> Steps { get; set; }
public virtual ICollection<Image> Images { get; set; }
public virtual ICollection<SubGoal> SubGoals { get; set; }
public CoreGoal()
{
}
}
And Image model is as following:
public class Image
{
[Key]
public long ImagelId { get; set; }
public byte[] Base64 { get; set; }
[ForeignKey("CoreGoalId")]
public long CoreGoalId { get; set; }
public Image()
{
}
}
My controller class:
[Route("api/[controller]")]
public class CoreGoalController : Controller
{
private readonly ICoreGoalRepository _coreGoalRepository;
//Controller
public CoreGoalController(ICoreGoalRepository coreGoalRepository) {
_coreGoalRepository = coreGoalRepository;
}
//Get methods
[HttpGet]
public IEnumerable<CoreGoal> GetAll()
{
return _coreGoalRepository.GetAllCoreGoals();
}
[HttpGet("{id}", Name = "GetCoreGoal")]
public IActionResult GetById(long id)
{
var item = _coreGoalRepository.Find(id);
if (item == null)
{
return NotFound();
}
return new ObjectResult(item);
}
//Create
[HttpPost]
public IActionResult Create([FromBody] CoreGoal item)
{
if (item == null)
{
return BadRequest();
}
_coreGoalRepository.CreateCoreGoal(item);
return CreatedAtRoute("GetCoreGoal", new { id = item.CoreGoalId }, item);
}
}
Repository:
public class CoreGoalRepository : ICoreGoalRepository
{
private readonly WebAPIDataContext _db;
public CoreGoalRepository(WebAPIDataContext db)
{
_db = db;
}
//Add new
public void CreateCoreGoal(CoreGoal coreGoal)
{
_db.CoreGoals.Add(coreGoal);
_db.SaveChanges();
}
//Get all
public IEnumerable<CoreGoal> GetAllCoreGoals()
{
return _db.CoreGoals
.Include(coreGoal => coreGoal.Benefits)
.Include(coreGoal => coreGoal.Steps)
.Include(coreGoal => coreGoal.Images)
.Include(coreGoal => coreGoal.SubGoals)
.ToList();
}
//Find specific
public CoreGoal Find(long key)
{
return _db.CoreGoals.FirstOrDefault(t => t.CoreGoalId == key);
}
}
public interface ICoreGoalRepository
{
void CreateCoreGoal(CoreGoal coreGoal);
IEnumerable<CoreGoal> GetAllCoreGoals();
CoreGoal Find(long key);
void DeleteCoreGoal(long id);
void UpdateCoreGoal(CoreGoal coreGoal);
}
When I do a POST request from swagger I get a template like:
{
"coreGoalId": 0,
"title": "string",
"effect": "string",
"target_Audience": "string",
"infrastructure": "string",
"benefits": [
{
"benefitId": 0,
"what": "string",
"coreGoalId": 0
}
],
"steps": [
{
"stepId": 0,
"what": "string",
"coreGoalId": 0
}
],
"images": [
{
"imagelId": 0,
"base64": "string",
"coreGoalId": 0
}
],
"subGoals": [
{
"subGoalId": 0,
"title": "string",
"priority": "string",
"audience": "string",
"social_aspects": "string",
"coreGoalId": 0,
"issues": [
{
"issueId": 0,
"title": "string",
"subGoalID": 0
}
]
}
]
}
If I POST like like this, my request fails with status 400, however if I remove
"images": [
{
"imagelId": 0,
"base64": "string",
"coreGoalId": 0
}
],
from this request, then it is successful. Why is it happening? All other models i.e. Benefit, Step are exactly identical to Image in structure.
UPDATE:
Changing base64 type from byte[] to string eliminates this problem but in that case while saving to my MySql database the big base64 string is chopped and kind of becomes useless to again form the image.

Hi this is my json file structure. so can you tell me sql table structure for this json file

{
"success":true,
"cityList":[
{
"id":3793,
"name":"New York",
"country":"USA",
"district":"New York",
"population":8008278,
"lastYearPopulation":6807036
},
{
"id":3794,
"name":"Los Angeles",
"country":"USA",
"district":"California",
"population":3694820,
"lastYearPopulation":3140597
},
{
"id":3795,
"name":"Chicago",
"country":"USA",
"district":"Illinois",
"population":2896016,
"lastYearPopulation":2461613
},
{
"id":3796,
"name":"Houston",
"country":"USA",
"district":"Texas",
"population":1953631,
"lastYearPopulation":1660586
},
{
"id":3797,
"name":"Philadelphia",
"country":"USA",
"district":"Pennsylvania",
"population":1517550,
"lastYearPopulation":1289917
},
{
"id":3798,
"name":"Phoenix",
"country":"USA",
"district":"Arizona",
"population":1321045,
"lastYearPopulation":1122888
},
{
"id":3799,
"name":"San Diego",
"country":"USA",
"district":"California",
"population":1223400,
"lastYearPopulation":1039890
},
{
"id":3800,
"name":"Dallas",
"country":"USA",
"district":"Texas",
"population":1188580,
"lastYearPopulation":1010293
},
{
"id":3801,
"name":"San Antonio",
"country":"USA",
"district":"Texas",
"population":1144646,
"lastYearPopulation":972949
},
{
"id":3802,
"name":"Detroit",
"country":"USA",
"district":"Michigan",
"population":951270,
"lastYearPopulation":808579
}],
"totalCount":100
}
Use Json2csharp and find out classes of your json. Should help.
Here's your classes:
public class CityList
{
public int id { get; set; }
public string name { get; set; }
public string country { get; set; }
public string district { get; set; }
public int population { get; set; }
public int lastYearPopulation { get; set; }
}
public class RootObject
{
public bool success { get; set; }
public List<CityList> cityList { get; set; }
public int totalCount { get; set; }
}