diff --git a/src/Umbraco.Core/Services/DictionaryItemService.cs b/src/Umbraco.Core/Services/DictionaryItemService.cs
index 6b99ea7e24..809a482096 100644
--- a/src/Umbraco.Core/Services/DictionaryItemService.cs
+++ b/src/Umbraco.Core/Services/DictionaryItemService.cs
@@ -168,7 +168,9 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem
// So ensure we set something that can be distinguished here.
if (dictionaryItem.CreateDate == default)
{
- dictionaryItem.CreateDate = DateTime.MinValue;
+ // Set such that it's prior to the update date, but not the default date which will be considered
+ // uninitialized and get reset to the current date at the repository.
+ dictionaryItem.CreateDate = DateTime.MinValue.AddHours(1);
}
if (dictionaryItem.UpdateDate == default)
diff --git a/src/Umbraco.Core/Services/LanguageService.cs b/src/Umbraco.Core/Services/LanguageService.cs
index 01a249dbd0..c815e490de 100644
--- a/src/Umbraco.Core/Services/LanguageService.cs
+++ b/src/Umbraco.Core/Services/LanguageService.cs
@@ -80,7 +80,27 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
///
public async Task> UpdateAsync(ILanguage language, Guid userKey)
- => await SaveAsync(
+ {
+ // Create and update dates aren't tracked for languages. They exist on ILanguage due to the
+ // inheritance from IEntity, but we don't store them.
+ // However we have logic in ServerEventSender that will provide SignalR events for created and update operations,
+ // where these dates are used to distinguish between the two (whether or not the entity has an identity cannot
+ // be used here, as these events fire after persistence when the identity is known for both creates and updates).
+ // So ensure we set something that can be distinguished here.
+ if (language.CreateDate == default)
+ {
+ // Set such that it's prior to the update date, but not the default date which will be considered
+ // uninitialized and get reset to the current date at the repository.
+ language.CreateDate = DateTime.MinValue.AddHours(1);
+ }
+
+ if (language.UpdateDate == default)
+ {
+ // TODO (V17): To align with updates of system dates, this needs to change to DateTime.UtcNow.
+ language.UpdateDate = DateTime.Now;
+ }
+
+ return await SaveAsync(
language,
() =>
{
@@ -101,6 +121,7 @@ internal sealed class LanguageService : RepositoryService, ILanguageService
AuditType.Save,
"Update Language",
userKey);
+ }
///
public async Task> CreateAsync(ILanguage language, Guid userKey)
diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DictionaryItemServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DictionaryItemServiceTests.cs
index e22ec36a5f..b32402872e 100644
--- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DictionaryItemServiceTests.cs
+++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/DictionaryItemServiceTests.cs
@@ -362,6 +362,11 @@ internal sealed class DictionaryItemServiceTests : UmbracoIntegrationTest
var result = await DictionaryItemService.UpdateAsync(item, Constants.Security.SuperUserKey);
Assert.True(result.Success);
+ // Verify that the create and update dates can be used to distinguish between creates
+ // and updates (as these fields are used in ServerEventSender to emit a "Created" or "Updated"
+ // event.
+ Assert.Greater(result.Result.UpdateDate, result.Result.CreateDate);
+
var updatedItem = await DictionaryItemService.GetAsync("Child");
Assert.NotNull(updatedItem);
diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LanguageServiceTests.cs b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LanguageServiceTests.cs
index faf23ace24..9710512515 100644
--- a/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LanguageServiceTests.cs
+++ b/tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Services/LanguageServiceTests.cs
@@ -191,6 +191,11 @@ internal sealed class LanguageServiceTests : UmbracoIntegrationTest
Assert.IsTrue(result.Success);
Assert.AreEqual(LanguageOperationStatus.Success, result.Status);
+ // Verify that the create and update dates can be used to distinguish between creates
+ // and updates (as these fields are used in ServerEventSender to emit a "Created" or "Updated"
+ // event.
+ Assert.Greater(result.Result.UpdateDate, result.Result.CreateDate);
+
// re-get
languageDaDk = await LanguageService.GetAsync(languageDaDk.IsoCode);
Assert.NotNull(languageDaDk);