public HttpResponseMessage Put(int id, ServiceModel.UpdateThingViewModel viewModel) { var thingEditor = context.GetAll <DomainModel.User>() .FirstOrDefault(u => u.Id == viewModel.EditedById); var thing = context.GetAll <DomainModel.Thing>() .FirstOrDefault(u => u.Id == id); if (thingEditor == null) { ModelState.AddModelError("", "Invalid Editor"); } if (thing == null) { ModelState.AddModelError("", "Invalid Thing"); } if (thing != null && thing.OwnerId != thingEditor.Id) { ModelState.AddModelError("", "A Thing can only be edited by its owner"); } if (!ModelState.IsValid) { return(Request.CreateResponse(HttpStatusCode.BadRequest, ModelState.ToJson())); } foreach (var userId in viewModel.AssignedTo) { //already assigned if (thing.AssignedTo.Any(at => at.AssignedToUserId == userId)) { continue; } var assignedTo = context.GetAll <DomainModel.User>() .FirstOrDefault(u => u.Id == userId); if (assignedTo == null) { throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound, "Invalid User Assigned to Thing")); } thing.AssignedTo.Add(new DomainModel.UserThing(thing, assignedTo, thingEditor)); } //removed users var removedUserIds = thing.AssignedTo.Select(at => at.AssignedToUserId).Except(viewModel.AssignedTo); var addedUserIds = viewModel.AssignedTo.Except(thing.AssignedTo.Select(at => at.AssignedToUserId)); var removedUserThings = thing.AssignedTo.Where(at => removedUserIds.Contains(at.AssignedToUserId)).ToList(); var newUserThings = thing.AssignedTo.Where(at => addedUserIds.Contains(at.AssignedToUserId)).ToList(); context.Delete(removedUserThings); thing.Description = viewModel.Description; context.SaveChanges(); emailService.ThingAssigned(newUserThings.Select(x => x.AssignedToUser).ToArray(), thing, thingEditor).Send(); emailService.ThingUnassigned(newUserThings.Select(x => x.AssignedToUser).ToArray(), thing, thingEditor).Send(); var sThing = thing.MapToServiceModel(); var response = Request.CreateResponse(HttpStatusCode.OK, sThing); response.Headers.Location = new Uri(Request.RequestUri, "/api/thing/" + thing.Id.ToString()); return(response); }