public HttpResponseMessageWrapper <Item> DeleteItem(HttpRequestMessage req, Guid id) { Operation operation = null; HttpStatusCode code = AuthenticateUser(req); if (code != HttpStatusCode.OK) { // user not authenticated return(ReturnResult <Item>(req, operation, code)); } // get the item from the message body if one was passed Item clientItem; if (req.Content.Headers.ContentLength > 0) { clientItem = null; code = ProcessRequestBody(req, out clientItem, out operation); if (code != HttpStatusCode.OK) // error encountered processing body { return(ReturnResult <Item>(req, operation, code)); } if (clientItem.ID != id) { // IDs must match TraceLog.TraceError("ItemResource.Delete: Bad Request (ID in URL does not match entity body)"); return(ReturnResult <Item>(req, operation, HttpStatusCode.BadRequest)); } } else { // otherwise get the client item from the database try { clientItem = this.StorageContext.Items.Single <Item>(i => i.ID == id); var session = GetSessionFromMessageHeaders(req); operation = this.StorageContext.CreateOperation(CurrentUser, req.Method.Method, null, clientItem, null, session); } catch (Exception) { // item not found - it may have been deleted by someone else. Return 200 OK along with a dummy item. TraceLog.TraceInfo("ItemResource.Delete: entity not found; returned OK anyway"); return(ReturnResult <Item>(req, operation, new Item() { Name = "Item Not Found" }, HttpStatusCode.OK)); } } try { Folder folder = this.StorageContext.Folders.Single <Folder>(tl => tl.ID == clientItem.FolderID); if (folder.UserID != CurrentUser.ID) { // requested item does not belong to the authenticated user, return 403 Forbidden TraceLog.TraceError("ItemResource.Delete: Forbidden (entity's folder does not belong to current user)"); return(ReturnResult <Item>(req, operation, HttpStatusCode.Forbidden)); } try { Item requestedItem = this.StorageContext.Items.Include("ItemTags").Include("FieldValues").Single <Item>(t => t.ID == id); // process the delete BEFORE deleting item, fields, references, etc. ItemProcessor ip = ItemProcessor.Create(CurrentUser, StorageContext, requestedItem.ItemTypeID); if (ip != null) { // do itemtype-specific processing ip.ProcessDelete(requestedItem); } // delete all the itemtags associated with this item if (requestedItem.ItemTags != null && requestedItem.ItemTags.Count > 0) { foreach (var tt in requestedItem.ItemTags.ToList()) { this.StorageContext.ItemTags.Remove(tt); } } // delete all the fieldvalues associated with this item if (requestedItem.FieldValues != null && requestedItem.FieldValues.Count > 0) { foreach (var fv in requestedItem.FieldValues.ToList()) { this.StorageContext.FieldValues.Remove(fv); } } bool multipleItemsDeleted = false; // delete all the items with ParentID of this item.ID (recursively, from the bottom up) multipleItemsDeleted = DeleteItemChildrenRecursively(StorageContext, requestedItem); // delete all ItemRef FieldValues with Value of this item.ID multipleItemsDeleted |= DeleteItemReferences(CurrentUser, StorageContext, requestedItem); // TODO: indicate using TimeStamp that multiple items were deleted this.StorageContext.Items.Remove(requestedItem); if (this.StorageContext.SaveChanges() < 1) { TraceLog.TraceError("Internal Server Error (database operation did not succeed)"); return(ReturnResult <Item>(req, operation, HttpStatusCode.InternalServerError)); } else { if (folder.Name.StartsWith("$") == false) { WorkflowHost.WorkflowHost.InvokeWorkflowForOperation(this.StorageContext, null, operation); } TraceLog.TraceInfo("Accepted"); return(ReturnResult <Item>(req, operation, requestedItem, HttpStatusCode.Accepted)); } } catch (Exception ex) { // item not found - it may have been deleted by someone else. Return 200 OK along with a dummy item. TraceLog.TraceInfo(String.Format("Exception in database operation, return OK : Exception[{0}]", ex.Message)); return(ReturnResult <Item>(req, operation, new Item() { Name = "Item Not Found" }, HttpStatusCode.OK)); } } catch (Exception ex) { // folder not found - return 404 Not Found TraceLog.TraceException(String.Format("Resource not found (Folder)"), ex); return(ReturnResult <Item>(req, operation, HttpStatusCode.NotFound)); } }