From aadae6334b860c76cbc05b1b6c06d879bf8de5ca Mon Sep 17 00:00:00 2001 From: Shannon Date: Fri, 30 Jan 2015 10:13:04 +1100 Subject: [PATCH 1/4] Fixes: U4-2038 Violation of PRIMARY KEY constraint 'PK_cmsContentPreviewXml' YSOD occurs when publishing content Conflicts: src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs src/Umbraco.Core/Umbraco.Core.csproj --- .../Models/ContentPreviewEntity.cs | 10 +- src/Umbraco.Core/Models/ContentXmlEntity.cs | 14 ++- .../Persistence/PetaPocoExtensions.cs | 91 +++++++++++++++++++ .../Persistence/RecordPersistenceType.cs | 9 ++ .../Repositories/ContentPreviewRepository.cs | 41 +++------ .../Repositories/ContentRepository.cs | 12 +-- .../Repositories/ContentXmlRepository.cs | 29 +++--- .../Repositories/MediaRepository.cs | 10 +- .../Repositories/MemberRepository.cs | 10 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 + 10 files changed, 154 insertions(+), 73 deletions(-) create mode 100644 src/Umbraco.Core/Persistence/RecordPersistenceType.cs diff --git a/src/Umbraco.Core/Models/ContentPreviewEntity.cs b/src/Umbraco.Core/Models/ContentPreviewEntity.cs index e9688ff3d5..2f843cf2a7 100644 --- a/src/Umbraco.Core/Models/ContentPreviewEntity.cs +++ b/src/Umbraco.Core/Models/ContentPreviewEntity.cs @@ -10,12 +10,14 @@ namespace Umbraco.Core.Models internal class ContentPreviewEntity : ContentXmlEntity where TContent : IContentBase { - public ContentPreviewEntity(bool previewExists, TContent content, Func xml) - : base(previewExists, content, xml) + public ContentPreviewEntity(TContent content, Func xml) + : base(content, xml) { - Version = content.Version; } - public Guid Version { get; private set; } + public Guid Version + { + get { return Content.Version; } + } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/ContentXmlEntity.cs b/src/Umbraco.Core/Models/ContentXmlEntity.cs index f137b3b418..0450fdc72e 100644 --- a/src/Umbraco.Core/Models/ContentXmlEntity.cs +++ b/src/Umbraco.Core/Models/ContentXmlEntity.cs @@ -11,13 +11,11 @@ namespace Umbraco.Core.Models internal class ContentXmlEntity : IAggregateRoot where TContent : IContentBase { - private readonly bool _entityExists; private readonly Func _xml; - public ContentXmlEntity(bool entityExists, TContent content, Func xml) - { + public ContentXmlEntity(TContent content, Func xml) + { if (content == null) throw new ArgumentNullException("content"); - _entityExists = entityExists; _xml = xml; Content = content; } @@ -32,6 +30,7 @@ namespace Umbraco.Core.Models { get { return _xml(Content); } } + public TContent Content { get; private set; } public int Id @@ -44,9 +43,14 @@ namespace Umbraco.Core.Models public DateTime CreateDate { get; set; } public DateTime UpdateDate { get; set; } + /// + /// Special case, always return false, this will cause the repositories managing + /// this object to always do an 'insert' but these are special repositories that + /// do an InsertOrUpdate on insert since the data for this needs to be managed this way + /// public bool HasIdentity { - get { return _entityExists; } + get { return false; } } public object DeepClone() diff --git a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs index faa247d4a9..d2971ad161 100644 --- a/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs +++ b/src/Umbraco.Core/Persistence/PetaPocoExtensions.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Data; +using System.Data.Common; +using System.Data.SqlClient; using System.Linq; using System.Text.RegularExpressions; using Umbraco.Core.Logging; @@ -18,6 +20,95 @@ namespace Umbraco.Core.Persistence internal static event CreateTableEventHandler NewTable; + /// + /// This will handle the issue of inserting data into a table when there can be a violation of a primary key or unique constraint which + /// can occur when two threads are trying to insert data at the exact same time when the data violates this constraint. + /// + /// + /// + /// + /// Returns the action that executed, either an insert or an update + /// + /// NOTE: If an insert occurred and a PK value got generated, the poco object passed in will contain the updated value. + /// + /// + /// In different databases, there are a few raw SQL options like MySql's ON DUPLICATE KEY UPDATE or MSSQL's MERGE WHEN MATCHED, but since we are + /// also supporting SQLCE for which this doesn't exist we cannot simply rely on the underlying database to help us here. So we'll actually need to + /// try to be as proficient as possible when we know this can occur and manually handle the issue. + /// + /// We do this by first trying to Update the record, this will return the number of rows affected. If it is zero then we insert, if it is one, then + /// we know the update was successful and the row was already inserted by another thread. If the rowcount is zero and we insert and get an exception, + /// that's due to a race condition, in which case we need to retry and update. + /// + internal static RecordPersistenceType InsertOrUpdate(this Database db, T poco) + where T : class + { + return db.InsertOrUpdate(poco, null, null); + } + + /// + /// This will handle the issue of inserting data into a table when there can be a violation of a primary key or unique constraint which + /// can occur when two threads are trying to insert data at the exact same time when the data violates this constraint. + /// + /// + /// + /// + /// If the entity has a composite key they you need to specify the update command explicitly + /// + /// Returns the action that executed, either an insert or an update + /// + /// NOTE: If an insert occurred and a PK value got generated, the poco object passed in will contain the updated value. + /// + /// + /// In different databases, there are a few raw SQL options like MySql's ON DUPLICATE KEY UPDATE or MSSQL's MERGE WHEN MATCHED, but since we are + /// also supporting SQLCE for which this doesn't exist we cannot simply rely on the underlying database to help us here. So we'll actually need to + /// try to be as proficient as possible when we know this can occur and manually handle the issue. + /// + /// We do this by first trying to Update the record, this will return the number of rows affected. If it is zero then we insert, if it is one, then + /// we know the update was successful and the row was already inserted by another thread. If the rowcount is zero and we insert and get an exception, + /// that's due to a race condition, in which case we need to retry and update. + /// + internal static RecordPersistenceType InsertOrUpdate(this Database db, + T poco, + string updateCommand, + object updateArgs) + where T : class + { + if (poco == null) throw new ArgumentNullException("poco"); + + var rowCount = updateCommand.IsNullOrWhiteSpace() + ? db.Update(poco) + : db.Update(updateCommand, updateArgs); + + if (rowCount > 0) return RecordPersistenceType.Update; + + try + { + db.Insert(poco); + return RecordPersistenceType.Insert; + } + //TODO: Need to find out if this is the same exception that will occur for all databases... pretty sure it will be + catch (SqlException ex) + { + //This will occur if the constraint was violated and this record was already inserted by another thread, + //at this exact same time, in this case we need to do an update + + rowCount = updateCommand.IsNullOrWhiteSpace() + ? db.Update(poco) + : db.Update(updateCommand, updateArgs); + + if (rowCount == 0) + { + //this would be strange! in this case the only circumstance would be that at the exact same time, 3 threads executed, one + // did the insert and the other somehow managed to do a delete precisely before this update was executed... now that would + // be real crazy. In that case we need to throw an exception. + throw new DataException("Record could not be inserted or updated"); + } + + return RecordPersistenceType.Update; + } + } + /// /// This will escape single @ symbols for peta poco values so it doesn't think it's a parameter /// diff --git a/src/Umbraco.Core/Persistence/RecordPersistenceType.cs b/src/Umbraco.Core/Persistence/RecordPersistenceType.cs new file mode 100644 index 0000000000..53140afe81 --- /dev/null +++ b/src/Umbraco.Core/Persistence/RecordPersistenceType.cs @@ -0,0 +1,9 @@ +namespace Umbraco.Core.Persistence +{ + internal enum RecordPersistenceType + { + Insert, + Update, + Delete + } +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs index c749dc1204..a7a8dc45f3 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentPreviewRepository.cs @@ -60,13 +60,20 @@ namespace Umbraco.Core.Persistence.Repositories { throw new NotImplementedException(); } + + //NOTE: Not implemented because all ContentPreviewEntity will always return false for having an Identity + protected override void PersistUpdatedItem(ContentPreviewEntity entity) + { + throw new NotImplementedException(); + } + #endregion protected override void PersistNewItem(ContentPreviewEntity entity) { if (entity.Content.HasIdentity == false) { - throw new InvalidOperationException("Cannot insert a preview for a content item that has no identity"); + throw new InvalidOperationException("Cannot insert or update a preview for a content item that has no identity"); } var previewPoco = new PreviewXmlDto @@ -77,33 +84,13 @@ namespace Umbraco.Core.Persistence.Repositories Xml = entity.Xml.ToString(SaveOptions.None) }; - Database.Insert(previewPoco); + //We need to do a special InsertOrUpdate here because we know that the PreviewXmlDto table has a composite key and thus + // a unique constraint which can be violated if 2+ threads try to execute the same insert sql at the same time. + Database.InsertOrUpdate(previewPoco, + //Since the table has a composite key, we need to specify an explit update statement + "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId=@NodeId AND versionId=@VersionId", + new {NodeId = previewPoco.NodeId, VersionId = previewPoco.VersionId, Xml = previewPoco.Xml, Timestamp = previewPoco.Timestamp}); } - protected override void PersistUpdatedItem(ContentPreviewEntity entity) - { - if (entity.Content.HasIdentity == false) - { - throw new InvalidOperationException("Cannot update a preview for a content item that has no identity"); - } - - var previewPoco = new PreviewXmlDto - { - NodeId = entity.Id, - Timestamp = DateTime.Now, - VersionId = entity.Version, - Xml = entity.Xml.ToString(SaveOptions.None) - }; - - Database.Update( - "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version", - new - { - Xml = previewPoco.Xml, - Timestamp = previewPoco.Timestamp, - Id = previewPoco.NodeId, - Version = previewPoco.VersionId - }); - } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index af79401137..c46fbcdc71 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -575,10 +575,8 @@ namespace Umbraco.Core.Persistence.Repositories /// /// public void AddOrUpdateContentXml(IContent content, Func xml) - { - var contentExists = Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0; - - _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(contentExists, content, xml)); + { + _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(content, xml)); } /// @@ -597,11 +595,7 @@ namespace Umbraco.Core.Persistence.Repositories /// public void AddOrUpdatePreviewXml(IContent content, Func xml) { - var previewExists = - Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", - new { Id = content.Id, Version = content.Version }) != 0; - - _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); + _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(content, xml)); } #endregion diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs index da076506a6..fa65359766 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentXmlRepository.cs @@ -55,6 +55,12 @@ namespace Umbraco.Core.Persistence.Repositories { get { throw new NotImplementedException(); } } + + //NOTE: Not implemented because all ContentXmlEntity will always return false for having an Identity + protected override void PersistUpdatedItem(ContentXmlEntity entity) + { + throw new NotImplementedException(); + } #endregion @@ -68,22 +74,21 @@ namespace Umbraco.Core.Persistence.Repositories { if (entity.Content.HasIdentity == false) { - throw new InvalidOperationException("Cannot insert an xml entry for a content item that has no identity"); + throw new InvalidOperationException("Cannot insert or update an xml entry for a content item that has no identity"); } - var poco = new ContentXmlDto { NodeId = entity.Id, Xml = entity.Xml.ToString(SaveOptions.None) }; - Database.Insert(poco); - } - - protected override void PersistUpdatedItem(ContentXmlEntity entity) - { - if (entity.Content.HasIdentity == false) + var poco = new ContentXmlDto { - throw new InvalidOperationException("Cannot update an xml entry for a content item that has no identity"); - } + NodeId = entity.Id, + Xml = entity.Xml.ToString(SaveOptions.None) + }; - var poco = new ContentXmlDto { NodeId = entity.Id, Xml = entity.Xml.ToString(SaveOptions.None) }; - Database.Update(poco); + //We need to do a special InsertOrUpdate here because we know that the ContentXmlDto table has a 1:1 relation + // with the content table and a record may or may not exist so the + // unique constraint which can be violated if 2+ threads try to execute the same insert sql at the same time. + Database.InsertOrUpdate(poco); + } + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 5bf55d3891..c155424ebe 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -181,18 +181,12 @@ namespace Umbraco.Core.Persistence.Repositories public void AddOrUpdateContentXml(IMedia content, Func xml) { - var contentExists = Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0; - - _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(contentExists, content, xml)); + _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(content, xml)); } public void AddOrUpdatePreviewXml(IMedia content, Func xml) { - var previewExists = - Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", - new { Id = content.Id, Version = content.Version }) != 0; - - _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); + _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(content, xml)); } protected override void PerformDeleteVersion(int id, Guid versionId) diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index c917a928d4..6a6375d4e8 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -609,18 +609,12 @@ namespace Umbraco.Core.Persistence.Repositories public void AddOrUpdateContentXml(IMember content, Func xml) { - var contentExists = Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0; - - _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(contentExists, content, xml)); + _contentXmlRepository.AddOrUpdate(new ContentXmlEntity(content, xml)); } public void AddOrUpdatePreviewXml(IMember content, Func xml) { - var previewExists = - Database.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", - new { Id = content.Id, Version = content.Version }) != 0; - - _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(previewExists, content, xml)); + _contentPreviewRepository.AddOrUpdate(new ContentPreviewEntity(content, xml)); } private IMember BuildFromDto(List dtos) diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 36192f03ac..9a378698ac 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -178,6 +178,7 @@ + From f4a0bcfc9659f4ff3a6684a36e046dccf94d1315 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 3 Feb 2015 13:15:15 +1100 Subject: [PATCH 2/4] updates nuspec --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 13986641bf..1396c2cdbd 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -28,7 +28,7 @@ - + From d4d5a355e3807f183d6b55af560772f975dc53c2 Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Tue, 10 Feb 2015 15:08:27 +0100 Subject: [PATCH 3/4] Update CDF dependency --- build/NuSpecs/UmbracoCms.Core.nuspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec index 1396c2cdbd..f99b436565 100644 --- a/build/NuSpecs/UmbracoCms.Core.nuspec +++ b/build/NuSpecs/UmbracoCms.Core.nuspec @@ -28,7 +28,7 @@ - + From a59dd32dd1e3fa868b5043141f09806a7e8c136d Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 18 Feb 2015 09:15:07 +0100 Subject: [PATCH 4/4] Updates cdf refs --- src/Umbraco.Web.UI/Umbraco.Web.UI.csproj | 4 ++-- src/Umbraco.Web.UI/packages.config | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 4 ++-- src/Umbraco.Web/packages.config | 2 +- src/umbraco.cms/packages.config | 2 +- src/umbraco.cms/umbraco.cms.csproj | 4 ++-- src/umbraco.controls/packages.config | 2 +- src/umbraco.controls/umbraco.controls.csproj | 6 +++--- src/umbraco.editorControls/packages.config | 2 +- src/umbraco.editorControls/umbraco.editorControls.csproj | 6 +++--- src/umbraco.macroRenderings/packages.config | 2 +- src/umbraco.macroRenderings/umbraco.macroRenderings.csproj | 6 +++--- 12 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index 18f621e518..bef82249db 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -101,9 +101,9 @@ {07fbc26b-2927-4a22-8d96-d644c667fecc} UmbracoExamine - + False - ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + ..\packages\ClientDependency.1.8.2.1\lib\net40\ClientDependency.Core.dll False diff --git a/src/Umbraco.Web.UI/packages.config b/src/Umbraco.Web.UI/packages.config index 135073bc5f..e82e96ed45 100644 --- a/src/Umbraco.Web.UI/packages.config +++ b/src/Umbraco.Web.UI/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index dbe4507d30..a881471247 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -93,9 +93,9 @@ {07fbc26b-2927-4a22-8d96-d644c667fecc} UmbracoExamine - + False - ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + ..\packages\ClientDependency.1.8.2.1\lib\net40\ClientDependency.Core.dll False diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index 85d33f5f6f..5aef6be88f 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/umbraco.cms/packages.config b/src/umbraco.cms/packages.config index fb9ebcc90d..c69c70cd18 100644 --- a/src/umbraco.cms/packages.config +++ b/src/umbraco.cms/packages.config @@ -1,6 +1,6 @@  - + diff --git a/src/umbraco.cms/umbraco.cms.csproj b/src/umbraco.cms/umbraco.cms.csproj index 3dc0894887..e21f0a8801 100644 --- a/src/umbraco.cms/umbraco.cms.csproj +++ b/src/umbraco.cms/umbraco.cms.csproj @@ -104,9 +104,9 @@ AllRules.ruleset - + False - ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + ..\packages\ClientDependency.1.8.2.1\lib\net40\ClientDependency.Core.dll False diff --git a/src/umbraco.controls/packages.config b/src/umbraco.controls/packages.config index 52f6561bd3..b286c9c1f4 100644 --- a/src/umbraco.controls/packages.config +++ b/src/umbraco.controls/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/umbraco.controls/umbraco.controls.csproj b/src/umbraco.controls/umbraco.controls.csproj index 4a312cbc6e..3176f80cee 100644 --- a/src/umbraco.controls/umbraco.controls.csproj +++ b/src/umbraco.controls/umbraco.controls.csproj @@ -1,4 +1,4 @@ - + Debug @@ -66,9 +66,9 @@ AllRules.ruleset - + False - ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + ..\packages\ClientDependency.1.8.2.1\lib\net40\ClientDependency.Core.dll diff --git a/src/umbraco.editorControls/packages.config b/src/umbraco.editorControls/packages.config index 52f6561bd3..b286c9c1f4 100644 --- a/src/umbraco.editorControls/packages.config +++ b/src/umbraco.editorControls/packages.config @@ -1,4 +1,4 @@  - + \ No newline at end of file diff --git a/src/umbraco.editorControls/umbraco.editorControls.csproj b/src/umbraco.editorControls/umbraco.editorControls.csproj index 09d22eef3a..25c6d10f62 100644 --- a/src/umbraco.editorControls/umbraco.editorControls.csproj +++ b/src/umbraco.editorControls/umbraco.editorControls.csproj @@ -1,4 +1,4 @@ - + Local @@ -112,9 +112,9 @@ {651E1350-91B6-44B7-BD60-7207006D7003} Umbraco.Web - + False - ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + ..\packages\ClientDependency.1.8.2.1\lib\net40\ClientDependency.Core.dll System diff --git a/src/umbraco.macroRenderings/packages.config b/src/umbraco.macroRenderings/packages.config index dfd94cd216..eab2063a33 100644 --- a/src/umbraco.macroRenderings/packages.config +++ b/src/umbraco.macroRenderings/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj b/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj index 1bbbe4d52b..ea7ece0490 100644 --- a/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj +++ b/src/umbraco.macroRenderings/umbraco.macroRenderings.csproj @@ -1,4 +1,4 @@ - + Local @@ -104,9 +104,9 @@ AllRules.ruleset - + False - ..\packages\ClientDependency.1.7.1.2\lib\ClientDependency.Core.dll + ..\packages\ClientDependency.1.8.2.1\lib\net40\ClientDependency.Core.dll False