public virtual IHttpActionResult CreateContent(string path, [FromBody] Dictionary <string, object> contentProperties, EPiServer.DataAccess.SaveAction action = EPiServer.DataAccess.SaveAction.Save) { path = path ?? ""; var parentContentRef = FindContentReference(path); if (parentContentRef == ContentReference.EmptyReference) { return(NotFound()); } if (!ReferenceExists(parentContentRef)) { return(NotFound()); } // Instantiate content of named type. if (contentProperties == null) { return(BadRequestErrorCode("BODY_EMPTY")); } foreach (String property in NonCreatingProperties) { if (contentProperties.ContainsKey(property)) { contentProperties.Remove(property); } } object contentTypeString; if (!(contentProperties.TryGetValue("ContentType", out contentTypeString) || contentProperties.TryGetValue("__EpiserverContentType", out contentTypeString))) { return(BadRequestValidationErrors(ValidationError.Required("ContentType"))); } if (contentProperties.ContainsKey("ContentType")) { contentProperties.Remove("ContentType"); } if (contentProperties.ContainsKey("__EpiserverContentType")) { contentProperties.Remove("__EpiserverContentType"); } if (!(contentTypeString is string)) { return(BadRequestValidationErrors(ValidationError.InvalidType("ContentType", typeof(string)))); } // Check ContentType. ContentType contentType = FindEpiserverContentType(contentTypeString); if (contentType == null) { return(BadRequestValidationErrors(ValidationError.CustomError("ContentType", "CONTENT_TYPE_INVALID", $"Could not find contentType {contentTypeString}"))); } if (!contentProperties.TryGetValue("Name", out object nameValue)) { return(BadRequestValidationErrors(ValidationError.Required("Name"))); } contentProperties.Remove("Name"); if (!(nameValue is string)) { return(BadRequestValidationErrors(ValidationError.InvalidType("Name", typeof(string)))); } EPiServer.DataAccess.SaveAction saveaction = action; if (contentProperties.ContainsKey("SaveAction") && (string)contentProperties["SaveAction"] == "Publish") { saveaction = EPiServer.DataAccess.SaveAction.Publish; contentProperties.Remove("SaveAction"); } if (contentProperties.ContainsKey("SaveAction") && (string)contentProperties["SaveAction"] == "RequestApproval") { saveaction = EPiServer.DataAccess.SaveAction.RequestApproval; contentProperties.Remove("SaveAction"); } if (contentProperties.ContainsKey("SaveAction") && ((string)contentProperties["SaveAction"]) == "CheckIn") { saveaction = EPiServer.DataAccess.SaveAction.CheckIn; contentProperties.Remove("SaveAction"); } // Create content. IContent content; CultureInfo cultureInfo = null; // Check if a Language tag is set. if (contentProperties.TryGetValue("__EpiserverCurrentLanguage", out object languageValue)) { if (!(languageValue is string)) { return(BadRequestValidationErrors(ValidationError.InvalidType("__EpiserverCurrentLanguage", typeof(string)))); } if (!TryGetCultureInfo((string)languageValue, out cultureInfo)) { if (cultureInfo == null || !GetLanguages().Any(ci => ci.TwoLetterISOLanguageName == cultureInfo.TwoLetterISOLanguageName)) { return(BadRequestInvalidLanguage(languageValue.ToString())); } cultureInfo = new CultureInfo(cultureInfo.TwoLetterISOLanguageName); } if (!GetLanguages().Any(ci => ci.TwoLetterISOLanguageName == cultureInfo.TwoLetterISOLanguageName)) { return(BadRequestInvalidLanguage(languageValue.ToString())); } cultureInfo = new CultureInfo(cultureInfo.TwoLetterISOLanguageName); if (_repo.TryGet <IContent>(parentContentRef, cultureInfo, out IContent parent)) { return(BadRequestLanguageBranchExists(parent, cultureInfo.TwoLetterISOLanguageName)); } content = _repo.CreateLanguageBranch <IContent>(parentContentRef, cultureInfo); } else { content = _repo.GetDefault <IContent>(parentContentRef, contentType.ID); } if (contentProperties.ContainsKey("__EpiserverCurrentLanguage")) { contentProperties.Remove("__EpiserverCurrentLanguage"); } content.Name = (string)nameValue; // Set all the other values. var errors = UpdateContentProperties(contentProperties, content); if (errors.Any()) { return(BadRequestValidationErrors(errors.ToArray())); } var validationErrors = _validationService.Validate(content); if (validationErrors.Any()) { return(BadRequestValidationErrors(validationErrors.Select(ValidationError.FromEpiserver).ToArray())); } // Save the reference with the requested save action. try { var createdReference = _repo.Save(content, saveaction); if (TryGetProject(out int projectId, out Project project)) { ProjectItem projectItem = new ProjectItem(projectId, content); _projectrepo.SaveItems(new ProjectItem[] { projectItem }); } return(Created(path, new { reference = createdReference.ID, __EpiserverCurrentLanguage = cultureInfo })); } catch (AccessDeniedException) { return(StatusCode(HttpStatusCode.Forbidden)); } catch (EPiServerException) { return(BadRequestValidationErrors(ValidationError.TypeCannotBeUsed("ContentType", contentType.Name, _repo.Get <IContent>(parentContentRef).GetOriginalType().Name))); } }
public virtual IHttpActionResult UpdateContent(string path, [FromBody] Dictionary <string, object> newProperties, EPiServer.DataAccess.SaveAction action = EPiServer.DataAccess.SaveAction.Save) { path = path ?? ""; var contentRef = FindContentReference(path); if (contentRef == ContentReference.EmptyReference) { return(NotFound()); } if (contentRef == ContentReference.RootPage) { return(BadRequestErrorCode("UPDATE_ROOT_NOT_ALLOWED")); } if (!TryGetCultureInfo(out string language, out CultureInfo cultureInfo)) { return(BadRequestInvalidLanguage(language)); } if (!_repo.TryGet(contentRef, cultureInfo, out IContent originalContent)) { return(NotFound()); } if (newProperties == null) { return(BadRequestErrorCode("BODY_EMPTY")); } foreach (String property in NonCreatingProperties) { if (newProperties.ContainsKey(property)) { newProperties.Remove(property); } } foreach (String property in NonUpdatingProperties) { if (newProperties.ContainsKey(property)) { newProperties.Remove(property); } } var content = (originalContent as IReadOnly).CreateWritableClone() as IContent; EPiServer.DataAccess.SaveAction saveaction = action; if (newProperties.ContainsKey("SaveAction") && ((string)newProperties["SaveAction"]) == "Publish") { saveaction = EPiServer.DataAccess.SaveAction.Publish; newProperties.Remove("SaveAction"); } if (newProperties.ContainsKey("SaveAction") && ((string)newProperties["SaveAction"]) == "RequestApproval") { saveaction = EPiServer.DataAccess.SaveAction.RequestApproval; newProperties.Remove("SaveAction"); } if (newProperties.ContainsKey("SaveAction") && ((string)newProperties["SaveAction"]) == "CheckIn") { saveaction = EPiServer.DataAccess.SaveAction.CheckIn; newProperties.Remove("SaveAction"); } IContent moveTo = null; if (newProperties.ContainsKey(MoveEntityToPropertyKey)) { if (!(newProperties[MoveEntityToPropertyKey] is string)) { return(BadRequestValidationErrors(ValidationError.InvalidType(MoveEntityToPropertyKey, typeof(string)))); } var moveToPath = (string)newProperties[MoveEntityToPropertyKey]; if (!moveToPath.StartsWith("/")) { return(BadRequestValidationErrors(ValidationError.CustomError(MoveEntityToPropertyKey, "FIELD_INVALID_FORMAT", $"{MoveEntityToPropertyKey} should start with a /"))); } if (!_repo.TryGet(FindContentReference(moveToPath.Substring(1)), out moveTo)) { return(BadRequestValidationErrors(ValidationError.CustomError(MoveEntityToPropertyKey, "TARGET_CONTAINER_NOT_FOUND", "The target container was not found"))); } newProperties.Remove(MoveEntityToPropertyKey); } if (newProperties.ContainsKey("Name")) { content.Name = newProperties["Name"].ToString(); newProperties.Remove("Name"); } // Store the new information in the object. var errors = UpdateContentProperties(newProperties, content); if (errors.Any()) { return(BadRequestValidationErrors(errors.ToArray())); } var validationErrors = _validationService.Validate(content); if (validationErrors.Any()) { return(BadRequestValidationErrors(validationErrors.Select(ValidationError.FromEpiserver).ToArray())); } if (!HasAccess(content, EPiServer.Security.AccessLevel.Edit | EPiServer.Security.AccessLevel.Publish)) { return(StatusCode(HttpStatusCode.Forbidden)); } if (moveTo != null) { if (!HasAccess(content, EPiServer.Security.AccessLevel.Read | EPiServer.Security.AccessLevel.Delete)) { return(StatusCode(HttpStatusCode.Forbidden)); } if (!HasAccess(moveTo, EPiServer.Security.AccessLevel.Create | EPiServer.Security.AccessLevel.Publish)) { return(StatusCode(HttpStatusCode.Forbidden)); } } //from here on we're going to try to save things to the database, we have tried to optimize the chance of succeeding above if (moveTo != null) { try { _repo.Move(contentRef, moveTo.ContentLink); } catch (ContentNotFoundException) { //even though we already check for this above, we still handle it here for cases that we might not have foreseen return(BadRequestValidationErrors(ValidationError.CustomError(MoveEntityToPropertyKey, "TARGET_CONTAINER_NOT_FOUND", "The target container was not found"))); } catch (AccessDeniedException) { //even though we already check for this above, we still handle it here for cases that we might not have foreseen return(StatusCode(HttpStatusCode.Forbidden)); } } try { var updatedReference = _repo.Save(content, saveaction); if (TryGetProject(out int projectId, out Project project)) { ProjectItem projectItem = new ProjectItem(projectId, content); _projectrepo.SaveItems(new ProjectItem[] { projectItem }); } return(Ok(new { reference = updatedReference.ToString() })); } catch (Exception) { if (moveTo != null) { //try to undo the move. We've tried using TransactionScope for this, but it doesn't play well with Episerver (caching, among other problems) _repo.Move(contentRef, originalContent.ParentLink); } throw; } }