![](/img/trans.png)
[英]An efficient way to convert JObject to class with Automapper (C#)
[英]trying to map JObject to c# class using AutoMapper, I'm getting NULL for the child elements
我有下面的代碼,使用 AutoMapper v4 一切正常,但是當我升級到 V8 時,它開始在子屬性中返回 null。
結果現在是 [{"Id":null,"Name":null},{"Id":null,"Name":null}]-TTR0
我的代碼有什么問題嗎?
using System;
using System.Collections.Generic;
using AutoMapper;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
public class WarehouseObj{
public Warehouse[] Whs { get; set; }
public string Location { get; set; }
}
public class Warehouse{
public string Id { get; set; }
public string Name {get; set; }
}
public class Program
{
public static void Main()
{
var jsonString = @"{ 'wareh': [{
'wid': '1234',
'wname': 'W0986E'
},{
'wid': '1235',
'wname': 'E0948T'
}], 'lc' : 'TTR0'}";
var config = new MapperConfiguration(cfg => {
cfg.CreateMap<JObject,WarehouseObj>()
.ForMember("Whs", opt=>{ opt.MapFrom(jo => jo["wareh"]); })
.ForMember("Location", opt=>{ opt.MapFrom(jo => jo["lc"]); });
cfg.CreateMap<JObject, Warehouse>()
.ForPath(dest => dest.Id, opt => { opt.MapFrom(src => src["wid"]); })
.ForPath(dest => dest.Name, opt => { opt.MapFrom(src => src["wname"]); });
});
IMapper mapper = config.CreateMapper();
var jArray = JObject.Parse(jsonString);
Console.WriteLine("{0}-{1}",JsonConvert.SerializeObject(mapper.Map<WarehouseObj>(jArray).Whs), mapper.Map<WarehouseObj>(jArray).Location);
}
}
解決此類問題的一種方法是將 json 字符串反序列化為具體類,例如
public class Wareh
{
public string wid { get; set; }
public string wname { get; set; }
}
public class Root
{
public List<Wareh> wareh { get; set; }
public string lc { get; set; }
}
然后你可以用靜態類型的源和目標屬性定義你的地圖,它會正常工作。 有關說明,請參閱下面的代碼。
using AutoMapper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
public class WarehouseObj
{
public Warehouse[] Whs { get; set; }
public string Location { get; set; }
}
public class Warehouse
{
public string Id { get; set; }
public string Name { get; set; }
}
public class Wareh
{
public string wid { get; set; }
public string wname { get; set; }
}
public class Root
{
public List<Wareh> wareh { get; set; }
public string lc { get; set; }
}
public class Program
{
public static void Main()
{
var jsonString = @"{ 'wareh': [{
'wid': '1234',
'wname': 'W0986E'
},{
'wid': '1235',
'wname': 'E0948T'
}], 'lc' : 'TTR0'}";
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Root, WarehouseObj>()
.ForMember(dest => dest.Whs, opts => opts.MapFrom(src => src.wareh))
.ForMember(dest => dest.Location, opts => opts.MapFrom(src => src.lc));
cfg.CreateMap<Wareh, Warehouse>()
.ForMember(dest => dest.Id, opts => opts.MapFrom(src => src.wid))
.ForMember(dest => dest.Name, opts => opts.MapFrom(src => src.wname));
});
IMapper mapper = config.CreateMapper();
var jArray = JsonConvert.DeserializeObject<Root>(jsonString);
var mapped = mapper.Map<WarehouseObj>(jArray);
Console.WriteLine("{0}-{1}", JsonConvert.SerializeObject(mapper.Map<WarehouseObj>(jArray).Whs), mapper.Map<WarehouseObj>(jArray).Location);
}
}
將第二個映射更改為JToken
而不是JObject
有效。
所以而不是:
cfg.CreateMap<JObject, Warehouse>()
用:
cfg.CreateMap<JToken, Warehouse>()
ForMember
而不是ForPath
。 至於為什么,我不太確定。 我目前的猜測是,有一些問題與解析JArray
的物品進入JObject
秒; 即使使用不太復雜的 json:
var json = @"[{
'wid': '1234',
'wname': 'W0986E'
},{
'wid': '1235',
'wname': 'E0948T'
}]
";
以下不起作用(即,它使用null
初始化Warehouse
屬性):
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<JObject, Warehouse>()
.ForMember(dest => dest.Id, opt => { opt.MapFrom(src => (string)src["wid"]); })
.ForMember(dest => dest.Name, opt => { opt.MapFrom(src => (string)src["wname"]); });
});
IMapper mapper = config.CreateMapper();
var jArray = JArray.Parse(json);
var des = mapper.Map<Warehouse[]>(jArray);
但是將其更改為使用JToken
會起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.