First of all, I know this question might be a dupplicate of Automapper entity framework foreign key is null, but none of the answers made it work for me and I'm facing some other weird issues and on top of that, I'm totally new to .NET Core, EF and Automapper :-).
The problem is that whenever I create or update a Post, which is linked to a Category, with Automapper, the category is saved in the Database, but it's not returned while it's supposed to and I really don't understand why. It's actually returning null. The GetPost method returns what I expect tho; this means that the FK are properly set.
This is the response I get, notice the "Category": null,
Here is my Post entity
public class Post
{
[Key]
[StringLength(450)]
public string Id { get; set; }
[Required]
[MaxLength(150)]
public string Title { get; set; }
[Required]
[MaxLength(2500)]
public string Content { get; set; }
[ForeignKey("UserId")]
public User User { get; set; }
public string UserId { get; set; }
[ForeignKey("CategoryId")]
public Category Category { get; set; }
public string CategoryId { get; set; }
}
My Category entity :
public class Category
{
[Key]
[StringLength(450)]
public string Id { get; set; }
[Required]
[MaxLength(150)]
public string Name { get; set; }
public int Weight { get; set; }
}
My Automapper configuration for a Post creation :
AutoMapper.Mapper.Initialize(config =>
{
config.CreateMap<Category, CategoryDto>();
config.CreateMap<Post, PostDto>();
config.CreateMap<PostForCreationDto, Post>();
});
And my PostForCreationDto :
public class PostForCreationDto
{
[Required]
[MaxLength(150)]
public string Title { get; set; }
[Required]
[MinLength(25)]
[MaxLength(2500)]
public string Content { get; set; }
[Required]
public string CategoryId { get; set; }
}
Here is how I try to create a post in my PostController :
public async Task<IActionResult> CreatePost([FromBody] PostForCreationDto post)
{
if (post == null)
{
return BadRequest();
}
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var user = await _userManager.GetUserAsync(HttpContext.User);
var result = Mapper.Map<Post>(post);
result.UserId = user.Id;
_postRepository.CreatePost(result);
if (!await _postRepository.SaveAsync())
{
return BadRequest();
}
var createdPost = Mapper.Map<PostDto>(result);
return Ok(createdPost);
}
The PostDto contains an Id, Title, Content, and both Category and User DTO's, nothing special here. The _postRepository.CreatePost(result); simply adds the Post to the Posts list of the DbContext (_context.Posts.Add(post);)
The CategoryId is in the payload I send so it should already be included.. But it doesn't seem to work. I tried to hardcode it (result.CategoryId = post.CategoryId;) with no luck. So I figured the only difference with the user is that I load it.. This makes no sense, but I just loaded the category and stocked it in a var (var category = _context.Categories.Where(c => c.Id == post.CategoryId).FirstOrDefault()) without even applying it, and suddenly the post.Category is filled, don't ask me why. Anyway, this is not a solution, I just tried it and couldn't find an answer.
I guess there is a way to create a Post and return all the created fields, including FK's, so if anyone here could guide me through, it would be more than appreciated !

DBContext.Postcall, add includeCategory