From 52b1a09de08d6865840cbdce63b8d7a9a7b2a98e Mon Sep 17 00:00:00 2001 From: Shannon Date: Thu, 21 Jan 2016 15:01:55 +0100 Subject: [PATCH] abstracts out the DocumentType, MemberType and MediaType editor models, since some contain different props than each other and now member properties contain different properties than each other. So we have a lot of generic insanity going on... it works though. --- .../Mapping/ContentTypeModelMappingTests.cs | 14 ++-- .../Repositories/ContentTypeRepositoryTest.cs | 8 +-- .../src/common/services/util.service.js | 2 +- .../umbraco/config/lang/en_us.xml | 4 ++ .../Editors/ContentTypeController.cs | 14 ++-- .../Editors/ContentTypeControllerBase.cs | 13 ++-- .../Editors/MediaTypeController.cs | 12 ++-- .../Editors/MemberTypeController.cs | 12 ++-- .../ContentTypeCompositionDisplay.cs | 40 ++++++----- .../Models/ContentEditing/ContentTypeSave.cs | 67 +++++++++++-------- ...tTypeDisplay.cs => DocumentTypeDisplay.cs} | 51 +++++++------- .../Models/ContentEditing/DocumentTypeSave.cs | 43 ++++++++++++ .../Models/ContentEditing/MediaTypeDisplay.cs | 10 +++ .../Models/ContentEditing/MediaTypeSave.cs | 12 ++++ .../ContentEditing/MemberPropertyTypeBasic.cs | 17 +++++ .../MemberPropertyTypeDisplay.cs | 14 ++++ .../ContentEditing/MemberTypeDisplay.cs | 10 +++ .../Models/ContentEditing/MemberTypeSave.cs | 10 +++ .../ContentEditing/PropertyGroupBasic.cs | 29 +++++--- .../ContentEditing/PropertyGroupDisplay.cs | 5 +- .../ContentEditing/PropertyTypeDisplay.cs | 16 ++--- .../AvailablePropertyEditorsResolver.cs | 3 +- .../Models/Mapping/ContentTypeModelMapper.cs | 43 ++++++------ .../ContentTypeModelMapperExtensions.cs | 26 ++++--- .../Mapping/PropertyGroupDisplayResolver.cs | 17 +++++ .../Mapping/PropertyTypeGroupResolver.cs | 35 +++++----- src/Umbraco.Web/Umbraco.Web.csproj | 27 +++++++- 27 files changed, 377 insertions(+), 177 deletions(-) rename src/Umbraco.Web/Models/ContentEditing/{ContentTypeDisplay.cs => DocumentTypeDisplay.cs} (83%) create mode 100644 src/Umbraco.Web/Models/ContentEditing/DocumentTypeSave.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/MediaTypeDisplay.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/MediaTypeSave.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeBasic.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeDisplay.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/MemberTypeDisplay.cs create mode 100644 src/Umbraco.Web/Models/ContentEditing/MemberTypeSave.cs create mode 100644 src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs diff --git a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs index 76d1220ea3..71d53e9167 100644 --- a/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs +++ b/src/Umbraco.Tests/Models/Mapping/ContentTypeModelMappingTests.cs @@ -195,7 +195,7 @@ namespace Umbraco.Tests.Models.Mapping //Act - var result = Mapper.Map(contentType); + var result = Mapper.Map(contentType); //Assert @@ -289,7 +289,7 @@ namespace Umbraco.Tests.Models.Mapping } }; - var contentType = new ContentTypeSave + var contentType = new DocumentTypeSave { Id = 0, ParentId = -1, @@ -394,7 +394,7 @@ namespace Umbraco.Tests.Models.Mapping //Act - var result = Mapper.Map(contentType); + var result = Mapper.Map(contentType); //Assert @@ -443,9 +443,9 @@ namespace Umbraco.Tests.Models.Mapping } - private ContentTypeSave CreateContentTypeSave() + private DocumentTypeSave CreateContentTypeSave() { - return new ContentTypeSave + return new DocumentTypeSave { Alias = "test", AllowAsRoot = true, @@ -495,9 +495,9 @@ namespace Umbraco.Tests.Models.Mapping }; } - private ContentTypeSave CreateCompositionContentTypeSave() + private DocumentTypeSave CreateCompositionContentTypeSave() { - return new ContentTypeSave + return new DocumentTypeSave { Alias = "test", AllowAsRoot = true, diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs index 7be732fecb..abe67c9766 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentTypeRepositoryTest.cs @@ -297,7 +297,7 @@ namespace Umbraco.Tests.Persistence.Repositories // there is NO mapping from display to contentType, but only from save // to contentType, so if we want to test, let's to it properly! - var display = Mapper.Map(contentType); + var display = Mapper.Map(contentType); var save = MapToContentTypeSave(display); var mapped = Mapper.Map(save); @@ -358,9 +358,9 @@ namespace Umbraco.Tests.Persistence.Repositories // this is for tests only because it makes no sense at all to have such a // mapping defined, we only need it for the weird tests that use it - private ContentTypeSave MapToContentTypeSave(ContentTypeDisplay display) + private DocumentTypeSave MapToContentTypeSave(DocumentTypeDisplay display) { - return new ContentTypeSave + return new DocumentTypeSave { // EntityBasic Name = display.Name, @@ -410,7 +410,7 @@ namespace Umbraco.Tests.Persistence.Repositories // there is NO mapping from display to contentType, but only from save // to contentType, so if we want to test, let's to it properly! - var display = Mapper.Map(contentType); + var display = Mapper.Map(contentType); var save = MapToContentTypeSave(display); // modify... diff --git a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js index 4371c0d7a7..554790b6d0 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/util.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/util.service.js @@ -512,7 +512,7 @@ function umbDataFormatter() { }); var saveProperties = _.map(realProperties, function (p) { - var saveProperty = _.pick(p, 'id', 'alias', 'description', 'validation', 'label', 'sortOrder', 'dataTypeId', 'groupId'); + var saveProperty = _.pick(p, 'id', 'alias', 'description', 'validation', 'label', 'sortOrder', 'dataTypeId', 'groupId', 'memberCanEdit', 'showOnMemberProfile'); return saveProperty; }); diff --git a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml index cd0a3d3efd..3f9a62f47b 100644 --- a/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml +++ b/src/Umbraco.Web.UI/umbraco/config/lang/en_us.xml @@ -421,6 +421,7 @@ Log off Logout Macro + Mandatory Move More Name @@ -1058,6 +1059,9 @@ To manage your website, simply open the Umbraco back office and start adding con and all members using this type using this editor will get updated with the new settings + + Member can edit + Show on member profile diff --git a/src/Umbraco.Web/Editors/ContentTypeController.cs b/src/Umbraco.Web/Editors/ContentTypeController.cs index f9efb4e366..a325cdd005 100644 --- a/src/Umbraco.Web/Editors/ContentTypeController.cs +++ b/src/Umbraco.Web/Editors/ContentTypeController.cs @@ -56,7 +56,7 @@ namespace Umbraco.Web.Editors return Services.ContentTypeService.CountContentTypes(); } - public ContentTypeDisplay GetById(int id) + public DocumentTypeDisplay GetById(int id) { var ct = Services.ContentTypeService.GetContentType(id); if (ct == null) @@ -64,7 +64,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.NotFound); } - var dto = Mapper.Map(ct); + var dto = Mapper.Map(ct); return dto; } @@ -175,9 +175,9 @@ namespace Umbraco.Web.Editors : Request.CreateNotificationValidationErrorResponse(result.Exception.Message); } - public ContentTypeDisplay PostSave(ContentTypeSave contentTypeSave) + public DocumentTypeDisplay PostSave(DocumentTypeSave contentTypeSave) { - var savedCt = PerformPostSave( + var savedCt = PerformPostSave( contentTypeSave: contentTypeSave, getContentType: i => Services.ContentTypeService.GetContentType(i), saveContentType: type => Services.ContentTypeService.Save(type), @@ -206,7 +206,7 @@ namespace Umbraco.Web.Editors } }); - var display = Mapper.Map(savedCt); + var display = Mapper.Map(savedCt); display.AddSuccessNotification( Services.TextService.Localize("speechBubbles/contentTypeSavedHeader"), @@ -220,7 +220,7 @@ namespace Umbraco.Web.Editors /// /// /// - public ContentTypeDisplay GetEmpty(int parentId) + public DocumentTypeDisplay GetEmpty(int parentId) { IContentType ct; if (parentId != Constants.System.Root) @@ -233,7 +233,7 @@ namespace Umbraco.Web.Editors ct.Icon = "icon-document"; - var dto = Mapper.Map(ct); + var dto = Mapper.Map(ct); return dto; } diff --git a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs index de7835e0d5..8c10fc6bd0 100644 --- a/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs +++ b/src/Umbraco.Web/Editors/ContentTypeControllerBase.cs @@ -138,7 +138,8 @@ namespace Umbraco.Web.Editors /// /// /// - protected void ValidateComposition(ContentTypeSave contentTypeSave, IContentTypeComposition composition) + protected void ValidateComposition(ContentTypeSave contentTypeSave, IContentTypeComposition composition) + where TPropertyType : PropertyTypeBasic { var validateAttempt = Services.ContentTypeService.ValidateComposition(composition); if (validateAttempt == false) @@ -158,7 +159,7 @@ namespace Umbraco.Web.Editors ModelState.AddModelError(key, "Duplicate property aliases not allowed between compositions"); } - var display = Mapper.Map(composition); + var display = Mapper.Map(composition); //map the 'save' data on top display = Mapper.Map(contentTypeSave, display); display.Errors = ModelState.ToErrorDictionary(); @@ -181,14 +182,16 @@ namespace Umbraco.Web.Editors return CultureDictionary[text].IfNullOrWhiteSpace(text); } - protected TContentType PerformPostSave( - ContentTypeSave contentTypeSave, + protected TContentType PerformPostSave( + TContentTypeSave contentTypeSave, Func getContentType, Action saveContentType, bool validateComposition = true, - Action beforeCreateNew = null) + Action beforeCreateNew = null) where TContentType : class, IContentTypeComposition where TContentTypeDisplay : ContentTypeCompositionDisplay + where TContentTypeSave : ContentTypeSave + where TPropertyType : PropertyTypeBasic { var ctId = Convert.ToInt32(contentTypeSave.Id); var ct = ctId > 0 ? getContentType(ctId) : null; diff --git a/src/Umbraco.Web/Editors/MediaTypeController.cs b/src/Umbraco.Web/Editors/MediaTypeController.cs index 611c92e5a3..6abfb64b16 100644 --- a/src/Umbraco.Web/Editors/MediaTypeController.cs +++ b/src/Umbraco.Web/Editors/MediaTypeController.cs @@ -56,7 +56,7 @@ namespace Umbraco.Web.Editors return Services.ContentTypeService.CountContentTypes(); } - public ContentTypeCompositionDisplay GetById(int id) + public MediaTypeDisplay GetById(int id) { var ct = Services.ContentTypeService.GetMediaType(id); if (ct == null) @@ -64,7 +64,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.NotFound); } - var dto = Mapper.Map(ct); + var dto = Mapper.Map(ct); return dto; } @@ -114,12 +114,12 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(result); } - public ContentTypeCompositionDisplay GetEmpty(int parentId) + public MediaTypeDisplay GetEmpty(int parentId) { var ct = new MediaType(parentId); ct.Icon = "icon-picture"; - var dto = Mapper.Map(ct); + var dto = Mapper.Map(ct); return dto; } @@ -157,9 +157,9 @@ namespace Umbraco.Web.Editors : Request.CreateNotificationValidationErrorResponse(result.Exception.Message); } - public ContentTypeCompositionDisplay PostSave(ContentTypeSave contentTypeSave) + public ContentTypeCompositionDisplay PostSave(MediaTypeSave contentTypeSave) { - var savedCt = PerformPostSave( + var savedCt = PerformPostSave( contentTypeSave: contentTypeSave, getContentType: i => Services.ContentTypeService.GetMediaType(i), saveContentType: type => Services.ContentTypeService.Save(type)); diff --git a/src/Umbraco.Web/Editors/MemberTypeController.cs b/src/Umbraco.Web/Editors/MemberTypeController.cs index 5b95318dc1..5c697e518f 100644 --- a/src/Umbraco.Web/Editors/MemberTypeController.cs +++ b/src/Umbraco.Web/Editors/MemberTypeController.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.Editors private readonly MembershipProvider _provider; - public ContentTypeCompositionDisplay GetById(int id) + public MemberTypeDisplay GetById(int id) { var ct = Services.MemberTypeService.Get(id); if (ct == null) @@ -56,7 +56,7 @@ namespace Umbraco.Web.Editors throw new HttpResponseException(HttpStatusCode.NotFound); } - var dto = Mapper.Map(ct); + var dto = Mapper.Map(ct); return dto; } @@ -106,12 +106,12 @@ namespace Umbraco.Web.Editors return Request.CreateResponse(result); } - public ContentTypeCompositionDisplay GetEmpty() + public MemberTypeDisplay GetEmpty() { var ct = new MemberType(-1); ct.Icon = "icon-user"; - var dto = Mapper.Map(ct); + var dto = Mapper.Map(ct); return dto; } @@ -129,9 +129,9 @@ namespace Umbraco.Web.Editors return Enumerable.Empty(); } - public ContentTypeCompositionDisplay PostSave(ContentTypeSave contentTypeSave) + public ContentTypeCompositionDisplay PostSave(MemberTypeSave contentTypeSave) { - var savedCt = PerformPostSave( + var savedCt = PerformPostSave( contentTypeSave: contentTypeSave, getContentType: i => Services.MemberTypeService.Get(i), saveContentType: type => Services.MemberTypeService.Save(type), diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs index 5f6e2c5ce5..fb50fdec5c 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeCompositionDisplay.cs @@ -10,32 +10,26 @@ using Umbraco.Core.Models.Validation; namespace Umbraco.Web.Models.ContentEditing { - [DataContract(Name = "contentType", Namespace = "")] - public class ContentTypeCompositionDisplay : ContentTypeBasic, INotificationModel - { - public ContentTypeCompositionDisplay() + public abstract class ContentTypeCompositionDisplay : ContentTypeBasic, INotificationModel + { + protected ContentTypeCompositionDisplay() { //initialize collections so at least their never null - Groups = new List(); AllowedContentTypes = new List(); CompositeContentTypes = new List(); Notifications = new List(); - } - - //name, alias, icon, thumb, desc, inherited from basic - + } + + //name, alias, icon, thumb, desc, inherited from basic + //List view [DataMember(Name = "isContainer")] public bool IsContainer { get; set; } [DataMember(Name = "listViewEditorName")] [ReadOnly(true)] - public string ListViewEditorName { get; set; } + public string ListViewEditorName { get; set; } - //Tabs - [DataMember(Name = "groups")] - public IEnumerable Groups { get; set; } - //Allowed child types [DataMember(Name = "allowedContentTypes")] public IEnumerable AllowedContentTypes { get; set; } @@ -43,7 +37,7 @@ namespace Umbraco.Web.Models.ContentEditing //Compositions [DataMember(Name = "compositeContentTypes")] public IEnumerable CompositeContentTypes { get; set; } - + //Locked compositions [DataMember(Name = "lockedCompositeContentTypes")] public IEnumerable LockedCompositeContentTypes { get; set; } @@ -72,4 +66,20 @@ namespace Umbraco.Web.Models.ContentEditing [ReadOnly(true)] public IDictionary Errors { get; set; } } + + [DataContract(Name = "contentType", Namespace = "")] + public abstract class ContentTypeCompositionDisplay : ContentTypeCompositionDisplay + where TPropertyTypeDisplay : PropertyTypeDisplay + { + protected ContentTypeCompositionDisplay() + { + //initialize collections so at least their never null + Groups = new List>(); + } + + //Tabs + [DataMember(Name = "groups")] + public IEnumerable> Groups { get; set; } + + } } diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs index 17eb6bb35e..1f430730a3 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs +++ b/src/Umbraco.Web/Models/ContentEditing/ContentTypeSave.cs @@ -6,13 +6,13 @@ using Umbraco.Core; namespace Umbraco.Web.Models.ContentEditing { - [DataContract(Name = "contentType", Namespace = "")] - public class ContentTypeSave : ContentTypeBasic, IValidatableObject + /// + /// Abstract model used to save content types + /// + public abstract class ContentTypeSave : ContentTypeBasic, IValidatableObject { - public ContentTypeSave() + protected ContentTypeSave() { - //initialize collections so at least their never null - Groups = new List>(); AllowedContentTypes = new List(); CompositeContentTypes = new List(); } @@ -27,38 +27,49 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "allowAsRoot")] public bool AllowAsRoot { get; set; } - /// - /// The list of allowed templates to assign (template alias) - /// - [DataMember(Name = "allowedTemplates")] - public IEnumerable AllowedTemplates { get; set; } - //Allowed child types [DataMember(Name = "allowedContentTypes")] public IEnumerable AllowedContentTypes { get; set; } - /// - /// The default template to assign (template alias) - /// - [DataMember(Name = "defaultTemplate")] - public string DefaultTemplate { get; set; } - - //Tabs - [DataMember(Name = "groups")] - public IEnumerable> Groups { get; set; } - /// /// Custom validation /// /// /// - public IEnumerable Validate(ValidationContext validationContext) + public virtual IEnumerable Validate(ValidationContext validationContext) { - if (AllowedTemplates.Any(x => x.IsNullOrWhiteSpace())) - yield return new ValidationResult("Template value cannot be null", new[] {"AllowedTemplates"}); - if (CompositeContentTypes.Any(x => x.IsNullOrWhiteSpace())) - yield return new ValidationResult("Composite Content Type value cannot be null", new[] { "CompositeContentTypes" }); + yield return new ValidationResult("Composite Content Type value cannot be null", new[] {"CompositeContentTypes"}); + } + } + + /// + /// Abstract model used to save content types + /// + /// + public abstract class ContentTypeSave : ContentTypeSave + where TPropertyType : PropertyTypeBasic + { + protected ContentTypeSave() + { + Groups = new List>(); + } + + //Tabs + [DataMember(Name = "groups")] + public IEnumerable> Groups { get; set; } + + /// + /// Custom validation + /// + /// + /// + public override IEnumerable Validate(ValidationContext validationContext) + { + foreach (var validationResult in base.Validate(validationContext)) + { + yield return validationResult; + } var duplicateGroups = Groups.GroupBy(x => x.Name).Where(x => x.Count() > 1).ToArray(); if (duplicateGroups.Any()) @@ -70,7 +81,7 @@ namespace Umbraco.Web.Models.ContentEditing string.Format("Groups[{0}].Name", firstIndex) }); } - + var duplicateProperties = Groups.SelectMany(x => x.Properties).Where(x => x.Inherited == false).GroupBy(x => x.Alias).Where(x => x.Count() > 1).ToArray(); if (duplicateProperties.Any()) { @@ -85,7 +96,7 @@ namespace Umbraco.Web.Models.ContentEditing string.Format("Groups[{0}].Properties[{1}].Alias", groupIndex, propertyIndex) }); } - + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/DocumentTypeDisplay.cs similarity index 83% rename from src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs rename to src/Umbraco.Web/Models/ContentEditing/DocumentTypeDisplay.cs index 12d08ac683..65641e7f63 100644 --- a/src/Umbraco.Web/Models/ContentEditing/ContentTypeDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/DocumentTypeDisplay.cs @@ -1,26 +1,25 @@ -using System.Collections.Generic; -using System.Runtime.Serialization; - -namespace Umbraco.Web.Models.ContentEditing -{ - - [DataContract(Name = "contentType", Namespace = "")] - public class ContentTypeDisplay : ContentTypeCompositionDisplay - { - public ContentTypeDisplay() - { - //initialize collections so at least their never null - AllowedTemplates = new List(); - } - - //name, alias, icon, thumb, desc, inherited from the content type - - // Templates - [DataMember(Name = "allowedTemplates")] - public IEnumerable AllowedTemplates { get; set; } - - [DataMember(Name = "defaultTemplate")] - public EntityBasic DefaultTemplate { get; set; } - - } -} +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "contentType", Namespace = "")] + public class DocumentTypeDisplay : ContentTypeCompositionDisplay + { + public DocumentTypeDisplay() + { + //initialize collections so at least their never null + AllowedTemplates = new List(); + } + + //name, alias, icon, thumb, desc, inherited from the content type + + // Templates + [DataMember(Name = "allowedTemplates")] + public IEnumerable AllowedTemplates { get; set; } + + [DataMember(Name = "defaultTemplate")] + public EntityBasic DefaultTemplate { get; set; } + + } +} diff --git a/src/Umbraco.Web/Models/ContentEditing/DocumentTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/DocumentTypeSave.cs new file mode 100644 index 0000000000..cdf20dba8d --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/DocumentTypeSave.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Runtime.Serialization; +using Umbraco.Core; + +namespace Umbraco.Web.Models.ContentEditing +{ + /// + /// Model used to save a document type + /// + [DataContract(Name = "contentType", Namespace = "")] + public class DocumentTypeSave : ContentTypeSave + { + /// + /// The list of allowed templates to assign (template alias) + /// + [DataMember(Name = "allowedTemplates")] + public IEnumerable AllowedTemplates { get; set; } + + /// + /// The default template to assign (template alias) + /// + [DataMember(Name = "defaultTemplate")] + public string DefaultTemplate { get; set; } + + /// + /// Custom validation + /// + /// + /// + public override IEnumerable Validate(ValidationContext validationContext) + { + if (AllowedTemplates.Any(x => StringExtensions.IsNullOrWhiteSpace(x))) + yield return new ValidationResult("Template value cannot be null", new[] { "AllowedTemplates" }); + + foreach (var v in base.Validate(validationContext)) + { + yield return v; + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MediaTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/MediaTypeDisplay.cs new file mode 100644 index 0000000000..7063613d66 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/MediaTypeDisplay.cs @@ -0,0 +1,10 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "contentType", Namespace = "")] + public class MediaTypeDisplay : ContentTypeCompositionDisplay + { + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MediaTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/MediaTypeSave.cs new file mode 100644 index 0000000000..e20eb23125 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/MediaTypeSave.cs @@ -0,0 +1,12 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + /// + /// Model used to save a media type + /// + [DataContract(Name = "contentType", Namespace = "")] + public class MediaTypeSave : ContentTypeSave + { + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeBasic.cs b/src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeBasic.cs new file mode 100644 index 0000000000..dfe98461dd --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeBasic.cs @@ -0,0 +1,17 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + /// + /// Basic member property type + /// + [DataContract(Name = "contentType", Namespace = "")] + public class MemberPropertyTypeBasic : PropertyTypeBasic + { + [DataMember(Name = "showOnMemberProfile")] + public bool MemberCanViewProperty { get; set; } + + [DataMember(Name = "memberCanEdit")] + public bool MemberCanEditProperty { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeDisplay.cs new file mode 100644 index 0000000000..8f7d4be310 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/MemberPropertyTypeDisplay.cs @@ -0,0 +1,14 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "propertyType")] + public class MemberPropertyTypeDisplay : PropertyTypeDisplay + { + [DataMember(Name = "showOnMemberProfile")] + public bool MemberCanViewProperty { get; set; } + + [DataMember(Name = "memberCanEdit")] + public bool MemberCanEditProperty { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MemberTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/MemberTypeDisplay.cs new file mode 100644 index 0000000000..e6092a10f4 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/MemberTypeDisplay.cs @@ -0,0 +1,10 @@ +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "contentType", Namespace = "")] + public class MemberTypeDisplay : ContentTypeCompositionDisplay + { + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/MemberTypeSave.cs b/src/Umbraco.Web/Models/ContentEditing/MemberTypeSave.cs new file mode 100644 index 0000000000..98bfbf0fce --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/MemberTypeSave.cs @@ -0,0 +1,10 @@ +namespace Umbraco.Web.Models.ContentEditing +{ + /// + /// Model used to save a member type + /// + public class MemberTypeSave : ContentTypeSave + { + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/PropertyGroupBasic.cs b/src/Umbraco.Web/Models/ContentEditing/PropertyGroupBasic.cs index b8560ba342..2edf08f7bf 100644 --- a/src/Umbraco.Web/Models/ContentEditing/PropertyGroupBasic.cs +++ b/src/Umbraco.Web/Models/ContentEditing/PropertyGroupBasic.cs @@ -4,15 +4,8 @@ using System.Runtime.Serialization; namespace Umbraco.Web.Models.ContentEditing { - [DataContract(Name = "propertyGroup", Namespace = "")] - public class PropertyGroupBasic - where TPropertyType: PropertyTypeBasic + public abstract class PropertyGroupBasic { - public PropertyGroupBasic() - { - Properties = new List(); - } - /// /// Gets the special generic properties tab identifier. /// @@ -38,9 +31,6 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "id")] public int Id { get; set; } - [DataMember(Name = "properties")] - public IEnumerable Properties { get; set; } - [DataMember(Name = "sortOrder")] public int SortOrder { get; set; } @@ -48,4 +38,21 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "name")] public string Name { get; set; } } + + [DataContract(Name = "propertyGroup", Namespace = "")] + public class PropertyGroupBasic : PropertyGroupBasic + where TPropertyType: PropertyTypeBasic + { + public PropertyGroupBasic() + { + Properties = new List(); + } + + + + [DataMember(Name = "properties")] + public IEnumerable Properties { get; set; } + + + } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ContentEditing/PropertyGroupDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/PropertyGroupDisplay.cs index 1bae9c96d5..c31c93b206 100644 --- a/src/Umbraco.Web/Models/ContentEditing/PropertyGroupDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/PropertyGroupDisplay.cs @@ -5,11 +5,12 @@ using System.Runtime.Serialization; namespace Umbraco.Web.Models.ContentEditing { [DataContract(Name = "propertyGroup", Namespace = "")] - public class PropertyGroupDisplay : PropertyGroupBasic + public class PropertyGroupDisplay : PropertyGroupBasic + where TPropertyTypeDisplay : PropertyTypeDisplay { public PropertyGroupDisplay() { - Properties = new List(); + Properties = new List(); ParentTabContentTypeNames = new List(); ParentTabContentTypes = new List(); } diff --git a/src/Umbraco.Web/Models/ContentEditing/PropertyTypeDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/PropertyTypeDisplay.cs index a7ef06b52c..f0e725ed59 100644 --- a/src/Umbraco.Web/Models/ContentEditing/PropertyTypeDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/PropertyTypeDisplay.cs @@ -28,14 +28,14 @@ namespace Umbraco.Web.Models.ContentEditing [ReadOnly(true)] public bool Locked { get; set; } - //SD: Seems strange that this is needed - [DataMember(Name = "contentTypeId")] - [ReadOnly(true)] - public int ContentTypeId { get; set; } + ////SD: Seems strange that this is needed + //[DataMember(Name = "contentTypeId")] + //[ReadOnly(true)] + //public int ContentTypeId { get; set; } - //SD: Seems strange that this is needed - [DataMember(Name = "contentTypeName")] - [ReadOnly(true)] - public string ContentTypeName { get; set; } + ////SD: Seems strange that this is needed + //[DataMember(Name = "contentTypeName")] + //[ReadOnly(true)] + //public string ContentTypeName { get; set; } } } diff --git a/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs b/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs index fd9d1f388f..624c641d3b 100644 --- a/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/AvailablePropertyEditorsResolver.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.Linq; using AutoMapper; using Umbraco.Core.Models; diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs index 6ade23b6d5..bf4acc3c70 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapper.cs @@ -50,9 +50,9 @@ namespace Umbraco.Web.Models.Mapping .ForMember(type => type.UpdateDate, expression => expression.Ignore()) .ForMember(type => type.HasIdentity, expression => expression.Ignore()); - config.CreateMap() + config.CreateMap() //do the base mapping - .MapBaseContentTypeSaveToEntity(applicationContext) + .MapBaseContentTypeSaveToEntity(applicationContext) .ConstructUsing((source) => new ContentType(source.ParentId)) .ForMember(source => source.AllowedTemplates, expression => expression.Ignore()) .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) @@ -69,18 +69,18 @@ namespace Umbraco.Web.Models.Mapping ContentTypeModelMapperExtensions.AfterMapContentTypeSaveToEntity(source, dest, applicationContext); }); - config.CreateMap() + config.CreateMap() //do the base mapping - .MapBaseContentTypeSaveToEntity(applicationContext) + .MapBaseContentTypeSaveToEntity(applicationContext) .ConstructUsing((source) => new MediaType(source.ParentId)) .AfterMap((source, dest) => { ContentTypeModelMapperExtensions.AfterMapContentTypeSaveToEntity(source, dest, applicationContext); }); - config.CreateMap() + config.CreateMap() //do the base mapping - .MapBaseContentTypeSaveToEntity(applicationContext) + .MapBaseContentTypeSaveToEntity(applicationContext) .ConstructUsing((source) => new MemberType(source.ParentId)) .AfterMap((source, dest) => { @@ -89,13 +89,13 @@ namespace Umbraco.Web.Models.Mapping config.CreateMap().ConvertUsing(x => x.Alias); - config.CreateMap() + config.CreateMap() //map base logic - .MapBaseContentTypeEntityToDisplay(applicationContext, _propertyEditorResolver); + .MapBaseContentTypeEntityToDisplay(applicationContext, _propertyEditorResolver); - config.CreateMap() + config.CreateMap() //map base logic - .MapBaseContentTypeEntityToDisplay(applicationContext, _propertyEditorResolver) + .MapBaseContentTypeEntityToDisplay(applicationContext, _propertyEditorResolver) .AfterMap((source, dest) => { //default listview @@ -109,9 +109,9 @@ namespace Umbraco.Web.Models.Mapping } }); - config.CreateMap() + config.CreateMap() //map base logic - .MapBaseContentTypeEntityToDisplay(applicationContext, _propertyEditorResolver) + .MapBaseContentTypeEntityToDisplay(applicationContext, _propertyEditorResolver) .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) .ForMember(display => display.Notifications, expression => expression.Ignore()) @@ -141,7 +141,7 @@ namespace Umbraco.Web.Models.Mapping config.CreateMap() - .ConstructUsing((PropertyTypeBasic propertyTypeBasic) => + .ConstructUsing(propertyTypeBasic => { var dataType = applicationContext.Services.DataTypeService.GetDataTypeDefinitionById(propertyTypeBasic.DataTypeId); if (dataType == null) throw new NullReferenceException("No data type found with id " + propertyTypeBasic.DataTypeId); @@ -170,11 +170,14 @@ namespace Umbraco.Web.Models.Mapping #region *** Used for mapping on top of an existing display object from a save object *** - config.CreateMap() - .MapBaseContentTypeSaveToDisplay(); + config.CreateMap() + .MapBaseContentTypeSaveToDisplay(); + + config.CreateMap() + .MapBaseContentTypeSaveToDisplay(); - config.CreateMap() - .MapBaseContentTypeSaveToDisplay() + config.CreateMap() + .MapBaseContentTypeSaveToDisplay() .ForMember(dto => dto.AllowedTemplates, expression => expression.Ignore()) .ForMember(dto => dto.DefaultTemplate, expression => expression.Ignore()) .AfterMap((source, dest) => @@ -221,7 +224,7 @@ namespace Umbraco.Web.Models.Mapping //.ForMember(dest => dest.PropertyTypes, map => map.MapFrom(source => // source.Properties.Select(Mapper.Map))); - config.CreateMap, PropertyGroupDisplay>() + config.CreateMap, PropertyGroupDisplay>() .ForMember(dest => dest.Id, expression => expression.Condition(source => source.Id > 0)) .ForMember(g => g.ContentTypeId, expression => expression.Ignore()) .ForMember(g => g.ParentTabContentTypes, expression => expression.Ignore()) @@ -232,8 +235,8 @@ namespace Umbraco.Web.Models.Mapping .ForMember(g => g.Editor, expression => expression.Ignore()) .ForMember(g => g.View, expression => expression.Ignore()) .ForMember(g => g.Config, expression => expression.Ignore()) - .ForMember(g => g.ContentTypeId, expression => expression.Ignore()) - .ForMember(g => g.ContentTypeName, expression => expression.Ignore()) + //.ForMember(g => g.ContentTypeId, expression => expression.Ignore()) + //.ForMember(g => g.ContentTypeName, expression => expression.Ignore()) .ForMember(g => g.Locked, exp => exp.Ignore()); #endregion diff --git a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs index 5ad728ccab..b3c8baa96e 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentTypeModelMapperExtensions.cs @@ -47,10 +47,11 @@ namespace Umbraco.Web.Models.Mapping } } - public static IMappingExpression MapBaseContentTypeSaveToDisplay( + public static IMappingExpression MapBaseContentTypeSaveToDisplay( this IMappingExpression mapping) where TSource : ContentTypeSave - where TDestination : ContentTypeCompositionDisplay + where TDestination : ContentTypeCompositionDisplay + where TPropertyTypeDisplay : PropertyTypeDisplay { return mapping .ForMember(dto => dto.CreateDate, expression => expression.Ignore()) @@ -58,13 +59,15 @@ namespace Umbraco.Web.Models.Mapping .ForMember(dto => dto.ListViewEditorName, expression => expression.Ignore()) .ForMember(dto => dto.Notifications, expression => expression.Ignore()) .ForMember(dto => dto.Errors, expression => expression.Ignore()) - .ForMember(dto => dto.LockedCompositeContentTypes, exp => exp.Ignore()); + .ForMember(dto => dto.LockedCompositeContentTypes, exp => exp.Ignore()) + .ForMember(dto => dto.Groups, expression => expression.ResolveUsing(new PropertyGroupDisplayResolver())); } - public static IMappingExpression MapBaseContentTypeEntityToDisplay( + public static IMappingExpression MapBaseContentTypeEntityToDisplay( this IMappingExpression mapping, ApplicationContext applicationContext, Lazy propertyEditorResolver) where TSource : IContentTypeComposition - where TDestination : ContentTypeCompositionDisplay + where TDestination : ContentTypeCompositionDisplay + where TPropertyTypeDisplay : PropertyTypeDisplay, new() { return mapping .ForMember(display => display.Notifications, expression => expression.Ignore()) @@ -88,7 +91,7 @@ namespace Umbraco.Web.Models.Mapping .ForMember( dto => dto.Groups, - expression => expression.ResolveUsing(new PropertyTypeGroupResolver(applicationContext, propertyEditorResolver))); + expression => expression.ResolveUsing(new PropertyTypeGroupResolver(applicationContext, propertyEditorResolver))); } /// @@ -96,14 +99,16 @@ namespace Umbraco.Web.Models.Mapping /// /// /// + /// /// /// /// - public static IMappingExpression MapBaseContentTypeSaveToEntity( + public static IMappingExpression MapBaseContentTypeSaveToEntity( this IMappingExpression mapping, ApplicationContext applicationContext) //where TSource : ContentTypeCompositionDisplay - where TSource : ContentTypeSave - where TDestination : IContentTypeComposition + where TSource : ContentTypeSave + where TDestination : IContentTypeComposition + where TSourcePropertyType : PropertyTypeBasic { return mapping //only map id if set to something higher then zero @@ -200,7 +205,8 @@ namespace Umbraco.Web.Models.Mapping }); } - private static PropertyGroup MapSaveGroup(PropertyGroupBasic sourceGroup, IEnumerable destOrigGroups) + private static PropertyGroup MapSaveGroup(PropertyGroupBasic sourceGroup, IEnumerable destOrigGroups) + where TPropertyType: PropertyTypeBasic { PropertyGroup destGroup; if (sourceGroup.Id > 0) diff --git a/src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs b/src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs new file mode 100644 index 0000000000..52f7bc643a --- /dev/null +++ b/src/Umbraco.Web/Models/Mapping/PropertyGroupDisplayResolver.cs @@ -0,0 +1,17 @@ +using System.Collections.Generic; +using System.Linq; +using AutoMapper; +using Umbraco.Web.Models.ContentEditing; + +namespace Umbraco.Web.Models.Mapping +{ + internal class PropertyGroupDisplayResolver : ValueResolver, IEnumerable>> + where TSource : ContentTypeSave + where TPropertyTypeDisplay : PropertyTypeDisplay + { + protected override IEnumerable> ResolveCore(IEnumerable source) + { + return source.Select(Mapper.Map>); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs b/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs index bfd55cfbaa..61a8a56c3b 100644 --- a/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/PropertyTypeGroupResolver.cs @@ -9,7 +9,8 @@ using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping { - internal class PropertyTypeGroupResolver : ValueResolver> + internal class PropertyTypeGroupResolver : ValueResolver>> + where TPropertyType : PropertyTypeDisplay, new() { private readonly ApplicationContext _applicationContext; private readonly Lazy _propertyEditorResolver; @@ -40,15 +41,15 @@ namespace Umbraco.Web.Models.Mapping .FirstOrDefault(x => x != null); } - protected override IEnumerable ResolveCore(IContentTypeComposition source) + protected override IEnumerable> ResolveCore(IContentTypeComposition source) { // deal with groups - var groups = new List(); + var groups = new List>(); // add groups local to this content type foreach (var tab in source.PropertyGroups) { - var group = new PropertyGroupDisplay + var group = new PropertyGroupDisplay { Id = tab.Id, Inherited = false, @@ -73,7 +74,7 @@ namespace Umbraco.Web.Models.Mapping if (definingContentType == null) throw new Exception("PropertyGroup with id=" + tab.Id + " was not found on any of the content type's compositions."); - var group = new PropertyGroupDisplay + var group = new PropertyGroupDisplay { Id = tab.Id, Inherited = true, @@ -89,25 +90,25 @@ namespace Umbraco.Web.Models.Mapping } // deal with generic properties - var genericProperties = new List(); + var genericProperties = new List(); // add generic properties local to this content type var entityGenericProperties = source.PropertyTypes.Where(x => x.PropertyGroupId == null); - genericProperties.AddRange(MapProperties(entityGenericProperties, source, PropertyGroupDisplay.GenericPropertiesGroupId, false)); + genericProperties.AddRange(MapProperties(entityGenericProperties, source, PropertyGroupBasic.GenericPropertiesGroupId, false)); // add generic properties inherited through compositions var localGenericPropertyIds = genericProperties.Select(x => x.Id).ToArray(); var compositionGenericProperties = source.CompositionPropertyTypes .Where(x => x.PropertyGroupId == null // generic && localGenericPropertyIds.Contains(x.Id) == false); // skip those that are local - genericProperties.AddRange(MapProperties(compositionGenericProperties, source, PropertyGroupDisplay.GenericPropertiesGroupId, true)); + genericProperties.AddRange(MapProperties(compositionGenericProperties, source, PropertyGroupBasic.GenericPropertiesGroupId, true)); // if there are any generic properties, add the corresponding tab if (genericProperties.Any()) { - var genericTab = new PropertyGroupDisplay + var genericTab = new PropertyGroupDisplay { - Id = PropertyGroupDisplay.GenericPropertiesGroupId, + Id = PropertyGroupBasic.GenericPropertiesGroupId, Name = "Generic properties", ContentTypeId = source.Id, SortOrder = 999, @@ -133,7 +134,7 @@ namespace Umbraco.Web.Models.Mapping // now merge tabs based on names // as for one name, we might have one local tab, plus some inherited tabs var groupsGroupsByName = groups.GroupBy(x => x.Name).ToArray(); - groups = new List(); // start with a fresh list + groups = new List>(); // start with a fresh list foreach (var groupsByName in groupsGroupsByName) { // single group, just use it @@ -164,17 +165,17 @@ namespace Umbraco.Web.Models.Mapping return groups.OrderBy(x => x.SortOrder); } - private IEnumerable MapProperties(IEnumerable properties, IContentTypeBase contentType, int groupId, bool inherited) + private IEnumerable MapProperties(IEnumerable properties, IContentTypeBase contentType, int groupId, bool inherited) { - var mappedProperties = new List(); + var mappedProperties = new List(); foreach (var p in properties.Where(x => x.DataTypeDefinitionId != 0).OrderBy(x => x.SortOrder)) { var propertyEditor = _propertyEditorResolver.Value.GetByAlias(p.PropertyEditorAlias); var preValues = _applicationContext.Services.DataTypeService.GetPreValuesCollectionByDataTypeId(p.DataTypeDefinitionId); - mappedProperties.Add(new PropertyTypeDisplay - { + mappedProperties.Add(new TPropertyType + { Id = p.Id, Alias = p.Alias, Description = p.Description, @@ -184,8 +185,8 @@ namespace Umbraco.Web.Models.Mapping View = propertyEditor.ValueEditor.View, Config = propertyEditor.PreValueEditor.ConvertDbToEditor(propertyEditor.DefaultPreValues, preValues) , //Value = "", - ContentTypeId = contentType.Id, - ContentTypeName = contentType.Name, + //ContentTypeId = contentType.Id, + //ContentTypeName = contentType.Name, GroupId = groupId, Inherited = inherited, DataTypeId = p.DataTypeDefinitionId, diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 67af0ee515..2ae1436d58 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -99,14 +99,17 @@ ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.dll + False True ..\packages\AutoMapper.3.0.0\lib\net40\AutoMapper.Net4.dll + False True ..\packages\ClientDependency.1.8.4\lib\net45\ClientDependency.Core.dll + False True @@ -118,6 +121,7 @@ ..\packages\Examine.0.1.68.0\lib\Examine.dll + False True @@ -134,6 +138,7 @@ ..\packages\Markdown.1.14.4\lib\net45\MarkdownSharp.dll + False True @@ -166,8 +171,9 @@ ..\packages\Microsoft.Owin.Security.OAuth.3.0.1\lib\net45\Microsoft.Owin.Security.OAuth.dll - True ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + False + True False @@ -175,6 +181,7 @@ ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll + False True @@ -218,6 +225,7 @@ ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll + False True @@ -234,6 +242,7 @@ ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll + False True @@ -241,14 +250,17 @@ ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll + False True ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll + False True ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll + False True @@ -292,7 +304,8 @@ ..\packages\UrlRewritingNet.UrlRewriter.2.0.7\lib\UrlRewritingNet.UrlRewriter.dll - True + False + False @@ -308,15 +321,23 @@ - + + + + + + + + +