Home > front end >  Null values after mapping my DTO to my Database Entity
Null values after mapping my DTO to my Database Entity

Time:04-18

I have a problem when using AutoMapper to map my DTO on a POST Action to my database entity, since my database entity contains multiple references to other database entities, I used also multiple DTOs in my "WrapperDTO". But after mapping the Country/Address references on my Hotel-Model class are null.I can't figure out why, to me the mapping of the DTO -> Models seems to be right. Help would be highly appreciated.

Here are my Models and my DTOs:

Hotel Model:

public class Hotel
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double Rating { get; set; }

        [ForeignKey(nameof(AddressId))]
        public int AddressId { get; set; }
        public Address Address { get; set; }


        [ForeignKey(nameof(CountryId))]
        public int CountryId { get; set; }
        public Country Country { get; set; }

    }

Hotel DTOs:

public class CreateHotelDto : BaseHotelDto
{
    public CreateAddressDto AddressDto { get; set; }

    public CreateCountryDto CountryDto { get; set; }
}

public class BaseHotelDto
{
    public string Name { get; set; }
    public double Rating { get; set; }

}

Then my Address Model:

public class Address
{
    public int Id { get; set; }
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

And my Address DTOs:

public class CreateAddressDto : BaseAddressDto
{

}

public abstract class BaseAddressDto
{
    public string StreetAddress { get; set; }
    public string City { get; set; }
    public string State { get; set; }
    public string ZipCode { get; set; }
}

And at last my Country Model:

[Index(nameof(Country.Name), IsUnique = true)]
public class Country
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string CountryCode { get; set; }
    public string ShortName { get; set; }


    public virtual IList<Hotel> Hotels { get; set; }
}

And my Country DTOs:

[Index(nameof(CreateCountryDto.Name), IsUnique = true)]
public class CreateCountryDto : BaseCountryDto
{
    [Required]
    public string CountryCode { get; set; }
}

public abstract class BaseCountryDto
{
    [Required]
    public string Name { get; set; }
    public string ShortName { get; set; }
}

I also have this code in my "MapperConfig"-Class to map the DTOs to my Models:

 public MapperConfig()
        {
            #region CountryDbContext

            CreateMap<CreateCountryDto, Country>().ReverseMap();
            CreateMap<UpdateCountryDto, Country>().ReverseMap();
            CreateMap<CountryDetailsDto, Country>().ReverseMap();
            CreateMap<GetCountryDto, Country>().ReverseMap();


            #endregion

            #region AddressDbContext

            CreateMap<GetAddressDto, Address>().ReverseMap();
            CreateMap<UpdateAddressDto, Address>().ReverseMap();
            CreateMap<CreateAddressDto, Address>().ReverseMap();

            #endregion

            #region HotelDbContext

            CreateMap<HotelDetailsDto, Hotel>().ReverseMap();
            CreateMap<GetHotelDto, Hotel>().ReverseMap();
            CreateMap<CreateHotelDto, Hotel>().ReverseMap();
            CreateMap<UpdateHotelDto, Hotel>().ReverseMap();


            #endregion
        }

And of course I injected the AutoMapper Service using this:

builder.Services.AddAutoMapper(typeof(MapperConfig));

And in my controller I mapped the CreateHotelDto (where the CreateHotelDto is provided through a parameter) -> Hotel with this:

var mappedHotel = _mapper.Map<Hotel>(createHotelDto);

I used the following Dummy-JSON as data for the endpoint:

{
  "name": "Hotel Cirrus Shake",
  "rating": 3.0,
  "addressDto": {
    "streetAddress": "87 North Bear Hill St.",
    "city": "New York City",
    "state": "NY",
    "zipCode": "11756"
  },
  "countryDto": {
    "name": "USA",
    "shortName": "US",
    "countryCode": "840"
  }
}

The properties "Name" and "Rating" of the HotelDto are mapped correctly, however the AddressDto/CountryDto are not mapped correctly to their Model counterparts they are just null, the Ids are 0 but that's fine because they are auto incremented values on the SQL-Server and are therefore not needed.

Here's also a screenshot of my Debugger containing the relevant information about those objects:

Debugging Screen

CodePudding user response:

Change your MapperConfig like below:

public class MapperConfig : Profile
{
    public MapperConfig()
    {
        CreateMap<CreateCountryDto, Country>().ReverseMap();

        CreateMap<CreateAddressDto, Address>().ReverseMap();

        CreateMap<CreateHotelDto, Hotel>()
            .ForPath(a=>a.Address,o=>o.MapFrom(dto=>dto.AddressDto))   //add this...
            .ForPath(a=>a.Country, o=>o.MapFrom(dto=>dto.CountryDto))  //add this...
            .ReverseMap();
    }
}

Result:

enter image description here

  • Related