diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs
index b46781f76d..33131bbb52 100644
--- a/src/Umbraco.Core/Services/ContentService.cs
+++ b/src/Umbraco.Core/Services/ContentService.cs
@@ -1375,7 +1375,7 @@ namespace Umbraco.Core.Services
{
DeleteBlueprintsOfTypes(new[] {contentTypeId}, userId);
}
-
+
///
/// Saves a single object
///
diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs
index c575255eb2..6d0ca051a1 100644
--- a/src/Umbraco.Core/Services/IContentService.cs
+++ b/src/Umbraco.Core/Services/IContentService.cs
@@ -16,10 +16,10 @@ namespace Umbraco.Core.Services
/// explicitly. These methods will replace the normal ones in IContentService in v8 and this will be removed.
///
public interface IContentServiceOperations
- {
- //TODO: Remove this class in v8
-
- //TODO: There's probably more that needs to be added like the EmptyRecycleBin, etc...
+ {
+ //TODO: Remove this class in v8
+
+ //TODO: There's probably more that needs to be added like the EmptyRecycleBin, etc...
///
/// Saves a single object
@@ -99,7 +99,7 @@ namespace Umbraco.Core.Services
IEnumerable GetBlueprintsForContentTypes(params int[] documentTypeIds);
IContent GetBlueprintById(int id);
IContent GetBlueprintById(Guid id);
- void SaveBlueprint(IContent content, int userId = 0);
+ void SaveBlueprint(IContent content, int userId = 0);
void DeleteBlueprint(IContent content, int userId = 0);
IContent CreateContentFromBlueprint(IContent blueprint, string name, int userId = 0);
void DeleteBlueprintsOfType(int contentTypeId, int userId = 0);
@@ -179,7 +179,7 @@ namespace Umbraco.Core.Services
/// Alias of the
/// Optional id of the user creating the content
///
- IContent CreateContent(string name, Guid parentId, string contentTypeAlias, int userId = 0);
+ IContent CreateContent(string name, Guid parentId, string contentTypeAlias, int userId = 0);
///
/// Creates an object using the alias of the
@@ -644,7 +644,7 @@ namespace Umbraco.Core.Services
///
///
/// True if sorting succeeded, otherwise False
- bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true);
+ bool Sort(IEnumerable items, int userId = 0, bool raiseEvents = true);
///
/// Sorts a collection of objects by updating the SortOrder according
@@ -704,4 +704,4 @@ namespace Umbraco.Core.Services
///
IContent CreateContentWithIdentity(string name, int parentId, string contentTypeAlias, int userId = 0);
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs
index be78638a9e..64e3318b4c 100644
--- a/src/Umbraco.Web/Editors/ContentController.cs
+++ b/src/Umbraco.Web/Editors/ContentController.cs
@@ -95,8 +95,8 @@ namespace Umbraco.Web.Editors
public IEnumerable PostSaveUserGroupPermissions(UserGroupPermissionsSave saveModel)
{
if (saveModel.ContentId <= 0) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
-
- //TODO: Should non-admins be alowed to set granular permissions?
+
+ //TODO: Should non-admins be alowed to set granular permissions?
var content = Services.ContentService.GetById(saveModel.ContentId);
if (content == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
@@ -159,8 +159,8 @@ namespace Umbraco.Web.Editors
if (contentId <= 0) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
var content = Services.ContentService.GetById(contentId);
if (content == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound));
-
- //TODO: Should non-admins be able to see detailed permissions?
+
+ //TODO: Should non-admins be able to see detailed permissions?
var allUserGroups = Services.UserService.GetAllUserGroups();
@@ -379,7 +379,7 @@ namespace Umbraco.Web.Editors
///
/// Gets the children for the content id passed in
///
- ///
+ ///
[FilterAllowedOutgoingContent(typeof(IEnumerable>), "Items")]
public PagedResult> GetChildren(
int id,
@@ -409,9 +409,13 @@ namespace Umbraco.Web.Editors
return new PagedResult>(0, 0, 0);
}
+ // Note that we're excluding mapping of complex properties here to ensure that getting a larger amount of
+ // children for listviews and other similar cases, will not make everything halt when it tries to deserialize a
+ // complex property such as Nested Content.
var pagedResult = new PagedResult>(totalChildren, pageNumber, pageSize);
- pagedResult.Items = children
- .Select(Mapper.Map>);
+ pagedResult.Items = children.Select(content =>
+ Mapper.Map>(content,
+ opts => { opts.Items["ExcludeComplexProperties"] = true; }));
return pagedResult;
}
@@ -644,7 +648,7 @@ namespace Umbraco.Web.Editors
ShowMessageForPublishStatus(publishStatus.Result, display);
break;
}
-
+
//If the item is new and the operation was cancelled, we need to return a different
// status code so the UI can handle it since it won't be able to redirect since there
// is no Id to redirect to!
diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
index c54574a08a..36b9edc3f9 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs
@@ -195,7 +195,7 @@ namespace Umbraco.Web.Models.Mapping
{
var parent = _contentService.Value.GetById(source.ParentId);
path = parent == null ? "-1" : parent.Path;
- }
+ }
var permissions = svc.GetPermissionsForPath(
//TODO: This is certainly not ideal usage here - perhaps the best way to deal with this in the future is
diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
index e7104f2939..89be6859d1 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyBasicConverter.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using AutoMapper;
using Umbraco.Core;
using Umbraco.Core.Logging;
@@ -13,11 +14,13 @@ namespace Umbraco.Web.Models.Mapping
/// Creates a base generic ContentPropertyBasic from a Property
///
///
- internal class ContentPropertyBasicConverter : TypeConverter
+ internal class ContentPropertyBasicConverter : ITypeConverter
where T : ContentPropertyBasic, new()
{
protected IDataTypeService DataTypeService { get; private set; }
+ private static readonly List ComplexPropertyTypeAliases = new List {"Umbraco.NestedContent"};
+
public ContentPropertyBasicConverter(IDataTypeService dataTypeService)
{
DataTypeService = dataTypeService;
@@ -26,28 +29,45 @@ namespace Umbraco.Web.Models.Mapping
///
/// Assigns the PropertyEditor, Id, Alias and Value to the property
///
- ///
///
- protected override T ConvertCore(Property property)
+ public T Convert(ResolutionContext context)
{
+ var property = context.SourceValue as Property;
+ if (property == null)
+ throw new InvalidOperationException("Source value is not a property.");
+
var editor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias);
if (editor == null)
{
LogHelper.Error>(
"No property editor found, converting to a Label",
- new NullReferenceException("The property editor with alias " + property.PropertyType.PropertyEditorAlias + " does not exist"));
+ new NullReferenceException("The property editor with alias " +
+ property.PropertyType.PropertyEditorAlias + " does not exist"));
editor = PropertyEditorResolver.Current.GetByAlias(Constants.PropertyEditors.NoEditAlias);
}
- var result = new T
- {
- Id = property.Id,
- Value = editor.ValueEditor.ConvertDbToEditor(property, property.PropertyType, DataTypeService),
- Alias = property.Alias,
- PropertyEditor = editor,
- Editor = editor.Alias
- };
+ var result = new T
+ {
+ Id = property.Id,
+ Alias = property.Alias,
+ PropertyEditor = editor,
+ Editor = editor.Alias
+ };
+
+ // Complex properties such as Nested Content do not need to be mapped for simpler things like list views,
+ // where they will not make sense to use anyways. To avoid having to do unnecessary mapping on large
+ // collections of items in list views - we allow excluding mapping of certain properties.
+ var excludeComplexProperties = false;
+ if (context.Options.Items.ContainsKey("ExcludeComplexProperties"))
+ {
+ excludeComplexProperties = System.Convert.ToBoolean(context.Options.Items["ExcludeComplexProperties"]);
+ }
+ if (excludeComplexProperties == false || ComplexPropertyTypeAliases.Contains(property.PropertyType.PropertyEditorAlias) == false)
+ {
+ result.Value = editor.ValueEditor.ConvertDbToEditor(property, property.PropertyType, DataTypeService);
+ }
+
return result;
}
}
diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs
index 8267e46e25..632268ab2f 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDisplayConverter.cs
@@ -1,7 +1,5 @@
using System;
-using System.Linq;
-using Umbraco.Core;
-using Umbraco.Core.Configuration;
+using AutoMapper;
using Umbraco.Core.Models;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
@@ -21,27 +19,31 @@ namespace Umbraco.Web.Models.Mapping
_textService = textService;
}
- protected override ContentPropertyDisplay ConvertCore(Property originalProp)
+ public new ContentPropertyDisplay Convert(ResolutionContext context)
{
- var display = base.ConvertCore(originalProp);
+ var display = base.Convert(context);
+
+ var originalProperty = context.SourceValue as Property;
+ if (originalProperty == null)
+ throw new InvalidOperationException("Source value is not a property.");
var dataTypeService = DataTypeService;
- var preVals = dataTypeService.GetPreValuesCollectionByDataTypeId(originalProp.PropertyType.DataTypeDefinitionId);
+ var preVals = dataTypeService.GetPreValuesCollectionByDataTypeId(originalProperty.PropertyType.DataTypeDefinitionId);
//configure the editor for display with the pre-values
var valEditor = display.PropertyEditor.ValueEditor;
valEditor.ConfigureForDisplay(preVals);
//set the display properties after mapping
- display.Alias = originalProp.Alias;
- display.Description = originalProp.PropertyType.Description;
- display.Label = originalProp.PropertyType.Name;
+ display.Alias = originalProperty.Alias;
+ display.Description = originalProperty.PropertyType.Description;
+ display.Label = originalProperty.PropertyType.Name;
display.HideLabel = valEditor.HideLabel;
-
+
//add the validation information
- display.Validation.Mandatory = originalProp.PropertyType.Mandatory;
- display.Validation.Pattern = originalProp.PropertyType.ValidationRegExp;
-
+ display.Validation.Mandatory = originalProperty.PropertyType.Mandatory;
+ display.Validation.Pattern = originalProperty.PropertyType.ValidationRegExp;
+
if (display.PropertyEditor == null)
{
//display.Config = PreValueCollection.AsDictionary(preVals);
diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs
index f3f9fbe9d5..80b8c28309 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyDtoConverter.cs
@@ -1,7 +1,6 @@
using System;
-using Umbraco.Core;
+using AutoMapper;
using Umbraco.Core.Models;
-using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
@@ -17,9 +16,13 @@ namespace Umbraco.Web.Models.Mapping
{
}
- protected override ContentPropertyDto ConvertCore(Property originalProperty)
+ public new ContentPropertyDto Convert(ResolutionContext context)
{
- var propertyDto = base.ConvertCore(originalProperty);
+ var propertyDto = base.Convert(context);
+
+ var originalProperty = context.SourceValue as Property;
+ if (originalProperty == null)
+ throw new InvalidOperationException("Source value is not a property.");
var dataTypeService = DataTypeService;
@@ -27,7 +30,7 @@ namespace Umbraco.Web.Models.Mapping
propertyDto.ValidationRegExp = originalProperty.PropertyType.ValidationRegExp;
propertyDto.Description = originalProperty.PropertyType.Description;
propertyDto.Label = originalProperty.PropertyType.Name;
-
+
//TODO: We should be able to look both of these up at the same time!
propertyDto.DataType = dataTypeService.GetDataTypeDefinitionById(originalProperty.PropertyType.DataTypeDefinitionId);
propertyDto.PreValues = dataTypeService.GetPreValuesCollectionByDataTypeId(originalProperty.PropertyType.DataTypeDefinitionId);
diff --git a/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs
index 5e29bcf125..f401832020 100644
--- a/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/ContentPropertyModelMapper.cs
@@ -1,9 +1,7 @@
-using System;
-using AutoMapper;
+using AutoMapper;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Mapping;
-using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.Models.Mapping