我有以下通过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"
}
}
答案 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));