0

I have two models which are related like following:

public class Context { [Key] public long ContextId { get; set; } [Required] public string Role { get; set; } public ICollection<Connection> Connections { get; set; } public Context() { } } 

And

public class Connection { [Key] public long ConnectionId { get; set; } public string Name { get; set; } public long ContextId { get; set; } public Context Context { get; set; } public Connection() { } } 

I have a repository for Context:

public class ContextRepository: IContextRepository { private readonly WebAPIDataContext _db; public ContextRepository(WebAPIDataContext db) { _db = db; } public Context CreateContext(Context context) { _db.Contexts.Add(context); _db.SaveChanges(); return context; } public void DeleteContext(long id) { Context context = GetContext(id); if (context != null) { _db.Contexts.Remove(context); _db.SaveChanges(); } } public List<Context> GetAllContexts() { return _db.Contexts .Include(context => context.Connections) .ToList(); } public Context GetContext(long id) { return _db.Contexts.FirstOrDefault(o => o.ContextId == id); } public void UpdateContext(long id, Context context) { Context contextToUpdate = _db.Contexts.FirstOrDefault(o => o.ContextId == id); contextToUpdate.Role = context.Role; contextToUpdate.Connections = context.Connections; _db.Update(contextToUpdate); _db.SaveChanges(); } } 

Swagger gives me skeleton like following:

{ "contextId": 0, "role": "string", "connections": [ { "connectionId": 0, "name": "string", "contextId": 0, "context": {} } ] } 

If I fill "Role":"Worker" and "name":"Max" and do POST or similar in PUT then it gives me error:

{ "Connections[0].Context.Role": [ "The Role field is required." ] } 

Why is it so? I want to be able to POST or PUT data even if I do not fill connections related fields. Right now I have controller only for Context.

UPDATE: Controller:

[Route("api/[controller]")] public class ContextController : Controller { private readonly IContextRepository _contexts; public ContextController(IContextRepository contexts) { _contexts = contexts; } [HttpGet("")] public IActionResult GetAllContexts() { try { List<Context> contexts = _contexts.GetAllContexts(); return Ok(contexts); } catch (EntityNotFoundException<Context>) { return NotFound(); } } [HttpGet("{id}")] public IActionResult GetContext(long id) { Context context= _contexts.GetContext(id); if (context == null) { return NotFound(); } return Ok(context); } [HttpPost] public IActionResult CreateContext([FromBody] Context context) { if (ModelState.IsValid == false) { return BadRequest(ModelState); } Context createdContext= _contexts.CreateContext(context); if (createdContext== null) { return NotFound(); } return CreatedAtAction( nameof(GetContext), new { id = createdContext.ContextId}, createdContext); } [HttpPut("{id}")] public IActionResult UpdateContext(long id, [FromBody] Context context) { if (ModelState.IsValid == false) { return BadRequest(ModelState); } try { _contexts.UpdateContext(id, context); return Ok(); } catch (EntityNotFoundException<Context>) { return NotFound(); } } [HttpDelete("{id}")] public IActionResult DeleteCOntext(long id) { _contexts.DeleteContext(id); return Ok(); } } 
6
  • why you need context in your connection class when you have contextId, if you take out that will that works for you? Commented Mar 22, 2017 at 14:05
  • This is my very first time with asp.net core and I was following tutorial of model relationships (learn.microsoft.com/en-us/ef/core/modeling/relationships), it was given there so. I am building Web Api, in that case this navigation property isn't needed? Commented Mar 22, 2017 at 14:16
  • @Nitish Could you show me controller class? Commented Mar 22, 2017 at 14:28
  • @Turbot I updated my question with controller. Also, if I removed context from connection, the error was gone. However, my update method in repo is still somehow wrong. If I try to PUT updated data in existing connection (in a specific context), it throws me error. Commented Mar 22, 2017 at 14:34
  • Could you post the server exception? Commented Mar 22, 2017 at 14:52

1 Answer 1

0

This is because you have missed virtual keyword in your relation fields. Here adding virtual keyword to Connections field in Context class

 public virtual ICollection<Connection> Connections { get; set; } 

and to Context in Connection class will solve the issue

 public virtual Context Context { get; set; } 

For more info read this anwser

Sign up to request clarification or add additional context in comments.

10 Comments

Do I need to migrate and update database after adding virtual? Also, is public virtual Context Context { get; set; } at all necessary if I am building Web API (referring to first comment to my question)?
dont think so ... actually it depends on your mappings .. have you mapped ContextId field in Connection as a foreign key in your db
No, not explicitly. See my models in questions, that's what you are referring to right?
it will good if you put [ForeignKey("ContextId ")] attribute for the Context Field in connection
Okay, and do I really need public Context Context { get; set; } in connection if it's a web API? because only after removing it, I was able to get of the original error (see my comments below my question)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.