簡體   English   中英

嘗試使用 AutoMapper 將 JObject 映射到 c# 類,我的子元素為 NULL

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM