Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 试图使用AutoMapper将JObject映射到c类,子元素的值为NULL_C#_.net_Json.net_Automapper - Fatal编程技术网

C# 试图使用AutoMapper将JObject映射到c类,子元素的值为NULL

C# 试图使用AutoMapper将JObject映射到c类,子元素的值为NULL,c#,.net,json.net,automapper,C#,.net,Json.net,Automapper,我有下面的代码,使用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

我有下面的代码,使用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>()
以下操作不起作用,即它使用null初始化仓库属性:


但将其更改为使用JToken将起作用。

您可以在此处看到实时代码:因为您在评论中指出我的答案有助于您解决问题,请通过在V的左侧打勾将其标记为已接受。ForPath提供的选项范围小得多,即Condition、Ignore和MapFrom,而FormMember提供了其他转换,转换器、空替换、前置条件等。基于版本10的信息。我使用OfirD的解决方案修复了它,我无法将其反序列化为类,因为原始JSON结构是泛型的。
cfg.CreateMap<JToken, Warehouse>()
var json = @"[{
    'wid': '1234',
    'wname': 'W0986E'
  },{
    'wid': '1235',
    'wname': 'E0948T'
  }]
";
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);