I am trying to return a json array of my 3rd level depth related data, the issue here is that I get the result with the right property name but with a non clear value content, I failed to find a similar case to solve it. From the returned value message it looks like I am returning a queryable instead of the final result and I need to iterate over it, I've tried several ways to achive that but failed to find the right one.
The json result:
[
{
"registeredYear": "System.Linq.Enumerable+SelectEnumerableIterator`2[MyPath.Groups.GroupYear,System.String]"
}
]
The api endpoint
public async Task<ActionResult<IEnumerable<UserGroup>>> GetUserGroupYears(string email, string groupName)
{
var groupYears = await _repo.GetUserGroupYears(email, groupName);
var mappedEntities = _mapper.Map<GroupYearsListDto[]>(groupYears);
return Ok(mappedEntities);
}
The Repository method
public async Task<IEnumerable<UserGroup>> GetUserGroupYears(string email, string groupName)
{
var userGroupYears = _context.UserGroups
.Include(uo => uo.Group.GroupYears)
.ThenInclude( oy => oy.Year)
.Where(uo => uo.Group.Name == groupName && uo.Email == email );
return await userGoupYears.ToArrayAsync();
}
The used classes:
public class UserGroup
{
public string Email { get; set; }
public string UserId { get; set; }
public virtual User User { get; set; }
public string GroupId { get; set; }
public virtual Group Group { get; set; }
}
public class Group
{
public string Name { get; set; }
public virtual ICollection<UserGroup> Users { get; set; }
public virtual ICollection<GroupYear> GroupYears { get; }
}
public class GroupYear {
public string GroupId { get; set; }
public virtual Group Group { get; set; }
public string YearId { get; set; }
public virtual Year Year { get; set; }
public string RegisteredYear { get; set; }
}
The data transfer object and the mapping:
public class GroupYearsListDto
{
public string RegisteredYear { get; set; }
}
public CoreMappingProfiles()
{
CreateMap<UserGroup, GroupYearsListDto>()
.ForMember(
dest => dest.RegisteredYear,
opt => opt.MapFrom(src => src.Group.GroupYears.Select(x => x.RegisteredYear))
);
}
Update : Attaching a debugger shows that the repository method is returning an IQueryable including the correct values and the controller method makes something wrong when mapping. So I think the following line is responsible of that wrong result:
var mappedEntities = _mapper.Map<GroupYearsListDto[]>(GroupYears);
You are getting this JSON result:
[
{
"registeredYear": "System.Linq.Enumerable+SelectEnumerableIterator`2[MyPath.Groups.GroupYear,System.String]"
}
]
Because you are mapping an IEnumerable<string>
to a string
, as I mentioned in my comment. So essentially you are getting the same as:
CreateMap<UserGroup, GroupYearsListDto>()
.ForMember(
dest => dest.RegisteredYear,
opt => opt.MapFrom(src =>
{
IEnumerable<string> registeredYears = src.Group.GroupYears.Select(x => x.RegisteredYear);
return registeredYears.ToString();
})
);
And registeredYears.ToString()
is "System.Linq.Enumerable+SelectEnumerableIterator`2[MyPath.Groups.GroupYear,System.String]"
.
I imagine you will either:
src.Group.GroupYears.Select(x => x.RegisteredYear).Single()
string.Join(", ", src.Group.GroupYears.Select(x => x.RegisteredYear))
You have many options, but you need to actually return a string
to that property or else you will just get the ToString()
version of IEnumerable<string>
.
UPDATE:
Based on your comments below, you can try this:
Repository:
public IQueryable<GroupYear> GetGroupYears(string email, string groupName)
{
return _context
.UserGroups
.Where(x => x.Group.Name == groupName && x.Email == email)
.SelectMany(x => x.Group.GroupYears);
}
Controller:
public async Task<ActionResult<GroupYearsListDto[]>> GetGroupYears(string email, string groupName)
{
var groupYears = _repo.GetGroupYears(email, groupName);
var projection = _mapper.ProjectTo<GroupYearsListDto>(groupYears)
var mappedEntities = await projection.ToArrayAsync();
return Ok(mappedEntities);
}
Profile:
CreateMap<GroupYears, GroupYearsListDto>();
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.