Have an ASP.NET Core Web API with some services.
I have a database entity Products
:
public class Products
{
public int ProductId { get; set; }
public string ProductCode { get; set; }
public bool InStock { get; set; }
public DateTime CreateDate { get; set; }
}
and a model class working with Products
:
public class ProductModel
{
public int ProductId { get; set; }
public string ProductCode { get; set; }
}
public class ProductListModel
{
[JsonPropertyName("data")]
public List<ProductModel> ProductList { get; set; }
}
I need to take my products from my database and send them to an external API. But that external API needs JSON format like this:
{
"data": [
{
"ProductId": 1,
"ProductCode": "000001AD"
},
{
"ProductId": 2,
"ProductCode": "000001AB"
},
{
"ProductId": 3,
"ProductCode": "000002AA"
}
]
}
I'll take data from the database:
var products = _context.Products.Where(x => x.InStock).ToList();
Then I use AutoMapper, but test.data
always returns null:
var test = new ProductListModel();
_mapper.Map(products , test.ProductList);
But, if I serialized like this (without AutoMapper):
var products = _context.Products.Where(x => x.InStock).ToList();
var json = JsonConvert.SerializeObject(products );
var model = JsonConvert.DeserializeObject<ProductListModel>(json);
On the last line with the model
variable, I get this error:
Newtonsoft.Json.JsonSerializationException: 'Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'MyProject.Test.Models.ProductListModel' because the type requires a JSON object (e.g. {"name":"value"}) to deserialize correctly.
To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}) or change the deserialized type to an array or a type that implements a collection interface (e.g. ICollection, IList) like List that can be deserialized from a JSON array. JsonArrayAttribute can also be added to the type to force it to deserialize from a JSON array.
Path '', line 1, position 1.'
How can I take records from the database, put them in "data" and not get an error?
Thanks a lot.
CodePudding user response:
Solution: AutoMapper
Your Mapping Configuration / Profile should be as below:
MapperConfiguration _config = new MapperConfiguration(config =>
{
config.CreateMap<Products, ProductModel>();
config.CreateMap<List<Products>, ProductListModel>()
.ForMember(dest => dest.ProductList, opt => opt.MapFrom(src => src));
});
Mapping function
var test = new ProductListModel();
_mapper.Map(products, test);
Or
var test = new ProductListModel();
test.ProductProductList = _mapper.Map<List<ProductModel>>(products);
Solution: For Newtonsoft.Json Deserialize
products
is List<Products>
type. When you try to deserialize the JSON, you should deserialize it as the List<ProductListModel>
type.
var model = JsonConvert.DeserializeObject<List<ProductListModel>>(json);
Side note
JsonPropertyName
attribute is used for System.Text.Json
[JsonPropertyName("data")]
JsonProperty
attribute is used for Newtonsoft.Json
[JsonProperty("data")]
CodePudding user response:
you don't need any mapper, just fix your code. You are trying to deserialize List as ProductListModel, but they are very different. try this
var products = _context.Products
.Where(x => x.InStock)
.Select(x=> new ProductModel {
ProductId=x.ProductId,
ProductCode=x.ProductCode
})
.ToList();
ProductListModel productListModel= new ProductListModel { ProductList = products };
var json = JsonConvert.SerializeObject(productListModel);
ProductListModel model = JsonConvert.DeserializeObject<ProductListModel>(json);