Automapper将多个嵌套类映射到具有各种属性的一个类

时间:2012-11-15 20:46:14

标签: c# .net automapper

我有以下通过JSON请求填充的模型类:

public class Driver
{
    public string driverId { get; set; }
    public string url { get; set; }
    public string givenName { get; set; }
    public string familyName { get; set; }
    public string dateOfBirth { get; set; }
    public string nationality { get; set; }
}

public class Constructor
{
    public string constructorId { get; set; }
    public string url { get; set; }
    public string name { get; set; }
    public string nationality { get; set; }
}

public class DriverStanding
{
    public string position { get; set; }
    public string points { get; set; }
    public string wins { get; set; }
    public Driver Driver { get; set; }
    public List<Constructor> Constructors { get; set; }
}

public class StandingsList
{
    public string season { get; set; }
    public string round { get; set; }
    public List<DriverStanding> DriverStandings { get; set; }
}

public class StandingsTable
{
    public string season { get; set; }
    public List<StandingsList> StandingsLists { get; set; }
}

public class MRData
{
    public string xmlns { get; set; }
    public string series { get; set; }
    public string url { get; set; }
    public string limit { get; set; }
    public string offset { get; set; }
    public string total { get; set; }
    public StandingsTable StandingsTable { get; set; }
}

public class RootObject
{
    public MRData MRData { get; set; }
}

然后我有一个像这样的简单类:

public class DriverResults
{
    public string Season { get; set; }
    public string Points { get; set; }
    public List<Driver> Driver { get; set; }
}

public class Driver
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

当我请求JSON时,第一组类完全填充。我想从某些类中获取一些属性,例如/ RootObject.MRData.StandingsTable.Season = DriverResults.Season。下面是我的属性映射

驱动程序地图

givenName = FirstName

familyName = LastName

积分地图

points = Points

季节地图

赛季=赛季

这是我到目前为止所尝试的,但每次都是null:

        Mapper.CreateMap<MVCF1.API.Driver, MVCF1.Models.Driver>()
            .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.givenName))
            .ForMember(dest => dest.LastName, opt => opt.MapFrom(src => src.familyName));

        Mapper.CreateMap<MVCF1.API.DriverStanding, MVCF1.Models.DriverResults>()
            .ForMember(dest => dest.Points, opt => opt.MapFrom(src => src.points));

        Mapper.CreateMap<MVCF1.API.StandingsList, MVCF1.Models.DriverResults>()
            .ForMember(dest => dest.Season, opt => opt.MapFrom(src => src.season));

        Mapper.CreateMap<MVCF1.API.RootObject, MVCF1.Models.DriverResults>();

我查看了自定义类型转换器,但不确定如何在阅读文档时使用它们。

请帮助,谢谢。

更新:这是JSON返回

{
   "MRData":{
      "StandingsTable":{
         "StandingsLists":[
            {
               "DriverStandings":[
                  {
                     "Constructors":[
                        {
                           "constructorId":"red_bull",
                           "name":"Red Bull",
                           "nationality":"Austrian",
                           "url":"http://en.wikipedia.org/wiki/Red_Bull_Racing"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1987-07-03",
                        "driverId":"vettel",
                        "familyName":"Vettel",
                        "givenName":"Sebastian",
                        "nationality":"German",
                        "url":"http://en.wikipedia.org/wiki/Sebastian_Vettel"
                     },
                     "points":"255",
                     "position":"1",
                     "wins":"5"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"ferrari",
                           "name":"Ferrari",
                           "nationality":"Italian",
                           "url":"http://en.wikipedia.org/wiki/Scuderia_Ferrari"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1981-07-29",
                        "driverId":"alonso",
                        "familyName":"Alonso",
                        "givenName":"Fernando",
                        "nationality":"Spanish",
                        "url":"http://en.wikipedia.org/wiki/Fernando_Alonso"
                     },
                     "points":"245",
                     "position":"2",
                     "wins":"3"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"lotus_f1",
                           "name":"Lotus F1",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/Lotus_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1979-10-17",
                        "driverId":"raikkonen",
                        "familyName":"Räikkönen",
                        "givenName":"Kimi",
                        "nationality":"Finnish",
                        "url":"http://en.wikipedia.org/wiki/Kimi_R%C3%A4ikk%C3%B6nen"
                     },
                     "points":"198",
                     "position":"3",
                     "wins":"1"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"red_bull",
                           "name":"Red Bull",
                           "nationality":"Austrian",
                           "url":"http://en.wikipedia.org/wiki/Red_Bull_Racing"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1976-08-27",
                        "driverId":"webber",
                        "familyName":"Webber",
                        "givenName":"Mark",
                        "nationality":"Australian",
                        "url":"http://en.wikipedia.org/wiki/Mark_Webber"
                     },
                     "points":"167",
                     "position":"4",
                     "wins":"2"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"mclaren",
                           "name":"McLaren",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/McLaren"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1985-01-07",
                        "driverId":"hamilton",
                        "familyName":"Hamilton",
                        "givenName":"Lewis",
                        "nationality":"British",
                        "url":"http://en.wikipedia.org/wiki/Lewis_Hamilton"
                     },
                     "points":"165",
                     "position":"5",
                     "wins":"3"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"mclaren",
                           "name":"McLaren",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/McLaren"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1980-01-19",
                        "driverId":"button",
                        "familyName":"Button",
                        "givenName":"Jenson",
                        "nationality":"British",
                        "url":"http://en.wikipedia.org/wiki/Jenson_Button"
                     },
                     "points":"153",
                     "position":"6",
                     "wins":"2"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"ferrari",
                           "name":"Ferrari",
                           "nationality":"Italian",
                           "url":"http://en.wikipedia.org/wiki/Scuderia_Ferrari"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1981-04-25",
                        "driverId":"massa",
                        "familyName":"Massa",
                        "givenName":"Felipe",
                        "nationality":"Brazilian",
                        "url":"http://en.wikipedia.org/wiki/Felipe_Massa"
                     },
                     "points":"95",
                     "position":"7",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"mercedes",
                           "name":"Mercedes",
                           "nationality":"German",
                           "url":"http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1985-06-27",
                        "driverId":"rosberg",
                        "familyName":"Rosberg",
                        "givenName":"Nico",
                        "nationality":"German",
                        "url":"http://en.wikipedia.org/wiki/Nico_Rosberg"
                     },
                     "points":"93",
                     "position":"8",
                     "wins":"1"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"lotus_f1",
                           "name":"Lotus F1",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/Lotus_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1986-04-17",
                        "driverId":"grosjean",
                        "familyName":"Grosjean",
                        "givenName":"Romain",
                        "nationality":"French",
                        "url":"http://en.wikipedia.org/wiki/Romain_Grosjean"
                     },
                     "points":"90",
                     "position":"9",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"sauber",
                           "name":"Sauber",
                           "nationality":"Swiss",
                           "url":"http://en.wikipedia.org/wiki/Sauber"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1990-01-26",
                        "driverId":"perez",
                        "familyName":"Pérez",
                        "givenName":"Sergio",
                        "nationality":"Mexican",
                        "url":"http://en.wikipedia.org/wiki/Sergio_P%C3%A9rez"
                     },
                     "points":"66",
                     "position":"10",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"sauber",
                           "name":"Sauber",
                           "nationality":"Swiss",
                           "url":"http://en.wikipedia.org/wiki/Sauber"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1986-09-13",
                        "driverId":"kobayashi",
                        "familyName":"Kobayashi",
                        "givenName":"Kamui",
                        "nationality":"Japanese",
                        "url":"http://en.wikipedia.org/wiki/Kamui_Kobayashi"
                     },
                     "points":"58",
                     "position":"11",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"force_india",
                           "name":"Force India",
                           "nationality":"Indian",
                           "url":"http://en.wikipedia.org/wiki/Force_India"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1987-08-19",
                        "driverId":"hulkenberg",
                        "familyName":"Hülkenberg",
                        "givenName":"Nico",
                        "nationality":"German",
                        "url":"http://en.wikipedia.org/wiki/Nico_H%C3%BClkenberg"
                     },
                     "points":"49",
                     "position":"12",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"force_india",
                           "name":"Force India",
                           "nationality":"Indian",
                           "url":"http://en.wikipedia.org/wiki/Force_India"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1986-04-16",
                        "driverId":"resta",
                        "familyName":"di Resta",
                        "givenName":"Paul",
                        "nationality":"Scottish",
                        "url":"http://en.wikipedia.org/wiki/Paul_di_Resta"
                     },
                     "points":"46",
                     "position":"13",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"williams",
                           "name":"Williams",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/Williams_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1985-03-09",
                        "driverId":"maldonado",
                        "familyName":"Maldonado",
                        "givenName":"Pastor",
                        "nationality":"Venezuelan",
                        "url":"http://en.wikipedia.org/wiki/Pastor_Maldonado"
                     },
                     "points":"43",
                     "position":"14",
                     "wins":"1"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"mercedes",
                           "name":"Mercedes",
                           "nationality":"German",
                           "url":"http://en.wikipedia.org/wiki/Mercedes-Benz_in_Formula_One"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1969-01-03",
                        "driverId":"michael_schumacher",
                        "familyName":"Schumacher",
                        "givenName":"Michael",
                        "nationality":"German",
                        "url":"http://en.wikipedia.org/wiki/Michael_Schumacher"
                     },
                     "points":"43",
                     "position":"15",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"williams",
                           "name":"Williams",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/Williams_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1983-10-15",
                        "driverId":"bruno_senna",
                        "familyName":"Senna",
                        "givenName":"Bruno",
                        "nationality":"Brazilian",
                        "url":"http://en.wikipedia.org/wiki/Bruno_Senna"
                     },
                     "points":"30",
                     "position":"16",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"toro_rosso",
                           "name":"Toro Rosso",
                           "nationality":"Italian",
                           "url":"http://en.wikipedia.org/wiki/Scuderia_Toro_Rosso"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1990-04-25",
                        "driverId":"vergne",
                        "familyName":"Vergne",
                        "givenName":"Jean-Éric",
                        "nationality":"French",
                        "url":"http://en.wikipedia.org/wiki/Jean-%C3%89ric_Vergne"
                     },
                     "points":"12",
                     "position":"17",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"toro_rosso",
                           "name":"Toro Rosso",
                           "nationality":"Italian",
                           "url":"http://en.wikipedia.org/wiki/Scuderia_Toro_Rosso"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1989-07-01",
                        "driverId":"ricciardo",
                        "familyName":"Ricciardo",
                        "givenName":"Daniel",
                        "nationality":"Australian",
                        "url":"http://en.wikipedia.org/wiki/Daniel_Ricciardo"
                     },
                     "points":"10",
                     "position":"18",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"marussia",
                           "name":"Marussia",
                           "nationality":"Russian",
                           "url":"http://en.wikipedia.org/wiki/Marussia_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1982-03-18",
                        "driverId":"glock",
                        "familyName":"Glock",
                        "givenName":"Timo",
                        "nationality":"German",
                        "url":"http://en.wikipedia.org/wiki/Timo_Glock"
                     },
                     "points":"0",
                     "position":"19",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"caterham",
                           "name":"Caterham",
                           "nationality":"Malaysian",
                           "url":"http://en.wikipedia.org/wiki/Caterham_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1981-10-19",
                        "driverId":"kovalainen",
                        "familyName":"Kovalainen",
                        "givenName":"Heikki",
                        "nationality":"Finnish",
                        "url":"http://en.wikipedia.org/wiki/Heikki_Kovalainen"
                     },
                     "points":"0",
                     "position":"20",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"caterham",
                           "name":"Caterham",
                           "nationality":"Malaysian",
                           "url":"http://en.wikipedia.org/wiki/Caterham_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1984-09-08",
                        "driverId":"petrov",
                        "familyName":"Petrov",
                        "givenName":"Vitaly",
                        "nationality":"Russian",
                        "url":"http://en.wikipedia.org/wiki/Vitaly_Petrov"
                     },
                     "points":"0",
                     "position":"21",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"lotus_f1",
                           "name":"Lotus F1",
                           "nationality":"British",
                           "url":"http://en.wikipedia.org/wiki/Lotus_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1985-12-27",
                        "driverId":"ambrosio",
                        "familyName":"d'Ambrosio",
                        "givenName":"Jérôme",
                        "nationality":"Belgian",
                        "url":"http://en.wikipedia.org/wiki/J%C3%A9r%C3%B4me_d%27Ambrosio"
                     },
                     "points":"0",
                     "position":"22",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"marussia",
                           "name":"Marussia",
                           "nationality":"Russian",
                           "url":"http://en.wikipedia.org/wiki/Marussia_F1"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1990-02-15",
                        "driverId":"pic",
                        "familyName":"Pic",
                        "givenName":"Charles",
                        "nationality":"French",
                        "url":"http://en.wikipedia.org/wiki/Charles_Pic"
                     },
                     "points":"0",
                     "position":"23",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"hrt",
                           "name":"HRT",
                           "nationality":"Spanish",
                           "url":"http://en.wikipedia.org/wiki/Hispania_Racing"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1977-01-14",
                        "driverId":"karthikeyan",
                        "familyName":"Karthikeyan",
                        "givenName":"Narain",
                        "nationality":"Indian",
                        "url":"http://en.wikipedia.org/wiki/Narain_Karthikeyan"
                     },
                     "points":"0",
                     "position":"24",
                     "wins":"0"
                  },
                  {
                     "Constructors":[
                        {
                           "constructorId":"hrt",
                           "name":"HRT",
                           "nationality":"Spanish",
                           "url":"http://en.wikipedia.org/wiki/Hispania_Racing"
                        }
                     ],
                     "Driver":{
                        "dateOfBirth":"1971-02-24",
                        "driverId":"rosa",
                        "familyName":"de la Rosa",
                        "givenName":"Pedro",
                        "nationality":"Spanish",
                        "url":"http://en.wikipedia.org/wiki/Pedro_de_la_Rosa"
                     },
                     "points":"0",
                     "position":"25",
                     "wins":"0"
                  }
               ],
               "round":"18",
               "season":"2012"
            }
         ],
         "season":"2012"
      },
      "limit":"30",
      "offset":"0",
      "series":"f1",
      "total":"25",
      "url":"http://ergast.com/api/f1/current/driverstandings.json",
      "xmlns":"http://ergast.com/mrd/1.2"
   }
}

2 个答案:

答案 0 :(得分:2)

当@David建议运行断言时,我得到:

AutoMapper.AutoMapperConfigurationException : 
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
=================================================================================
DriverStanding -> DriverResults (Destination member list)
StackOverflow.Null.API.DriverStanding -> StackOverflow.Null.Models.DriverResults (Destination member list)
---------------------------------------------------------------------------------
Season
================================================================================
StandingsList -> DriverResults (Destination member list)
StackOverflow.Null.API.StandingsList -> StackOverflow.Null.Models.DriverResults (Destination member list)
--------------------------------------------------------------------------------
Points
Driver
=============================================================================
RootObject -> DriverResults (Destination member list)
StackOverflow.Null.API.RootObject -> StackOverflow.Null.Models.DriverResults (Destination member list)
-----------------------------------------------------------------------------
Season
Points
Driver

现在基本上你有一个对象(MRData),它有一个对象列表(StandingsList),它有一个对象列表(DriverStanding)。我假设在应用映射时,您希望将此1个复杂MRData对象展平为许多DriverResults个对象。这不是您可以直接使用配置轻松完成的操作,但您可以通过在各种对象上重新应用映射。

我认为您正在寻找与此解决方案类似的内容:AutoMapper and flattening nested arrays

更新 - 更新了符合更新要求的代码。

我已部分实施了该解决方案。

<强> MVCF1Profile.cs

namespace MVCF1
{
    using System.Collections.Generic;

    using AutoMapper;

    public class MVCF1Profile : Profile
    {
        public override string ProfileName
        {
            get { return "MVCF1Profile"; }
        }

        protected override void Configure()
        {
            AllowNullDestinationValues = true;
            AllowNullCollections = true;

            CreateMap<API.Driver, Models.Driver>()
                .ForMember(dest => dest.FirstName, opt => opt.MapFrom(src => src.givenName))
                .ForMember(dest => dest.LastName, opt => opt.MapFrom(src => src.familyName));

            CreateMap<API.StandingsList, Models.DriverResults>()
                .ForMember(dest => dest.Driver, opt => opt.MapFrom(src => src.DriverStandings.Select(ds => Mapper.Map<API.Driver, Models.Driver>(ds.Driver))))
                .ForMember(dest => dest.Points, opt => opt.Ignore());
        }
    }
}

单元测试:

[Test]
public void AutoMapper_Configuration_IsValid()
{
    Mapper.Initialize(m => m.AddProfile<MVCF1Profile>());
    Mapper.AssertConfigurationIsValid();
}

[Test]
public void AutoMapper_DriverMapping_IsValid()
{
    Mapper.Initialize(m => m.AddProfile<MVCF1Profile>());
    Mapper.AssertConfigurationIsValid();

    // Convert JSON string from question to RootObject instance
    var data = GetData();

    var ds = data.MRData.StandingsTable.StandingsLists.First();
    var driverResults = Mapper.Map<StandingsList, Models.DriverResults>(ds);

    Assert.That(driverResults, Is.Not.Null);
    Assert.That(driverResults.Points, Is.Null);
    Assert.That(driverResults.Season, Is.EqualTo("2012"));
    Assert.That(driverResults.Driver, Is.Not.Null);
    Assert.That(driverResults.Driver.Count(), Is.EqualTo(25));
}

作为参考我的GetData是(上面删除了json字符串)

private RootObject GetData()
{
    string jsonMessage;

    #region Initialise String
    jsonMessage = @"";
    #endregion

    var data = JsonConvert.DeserializeObject<RootObject>(jsonMessage);

    Assert.That(data, Is.Not.Null);
    Assert.That(data, Is.InstanceOf<RootObject>());
    Assert.That(data.MRData, Is.Not.Null);
    Assert.That(data.MRData, Is.InstanceOf<MRData>());
    Assert.That(data.MRData.StandingsTable, Is.Not.Null);
    Assert.That(data.MRData.StandingsTable, Is.InstanceOf<StandingsTable>());

    return data;
}

只需再次调用mapper,即可根据需要应用更高级别对象的映射。例如,一旦修复了配置,就可以执行以下操作:

Mapper.Map(root.MRData.StandingsTable, result);

这会将StandingsTable中的相应字段映射到结果目标。

答案 1 :(得分:1)

尝试这样的事情。您必须明确地深入了解src对象才能正确映射。 Automapper仅自动匹配具有相同名称且处于相同深度级别的属性。如果名称不匹配或嵌套在另一个名称中,则必须准确指定所需的属性。对象列表将正确映射而不更改Mapper.CreateMap&lt;&gt;(),但您必须从单个对象映射到单个对象或对象列表到另一个对象列表。

例如:

Mapper.CreateMap<MVCF1.API.RootObject, MVCF1.Models.DriverResults>()
    .ForMember(dest => dest.Season, opt.MapFrom(src => src.MRData.StandingsTable.season));