Closed SonniTost closed 1 year ago
Hi there @SonniTost!
Firstly, a big thank you for raising this issue. Every piece of feedback we receive helps us to make Umbraco better.
We really appreciate your patience while we wait for our team to have a look at this but we wanted to let you know that we see this and share with you the plan for what comes next.
We wish we could work with everyone directly and assess your issue immediately but we're in the fortunate position of having lots of contributions to work with and only a few humans who are able to do it. We are making progress though and in the meantime, we will keep you in the loop and let you know when we have any questions.
Thanks, from your friendly Umbraco GitHub bot :robot: :slightly_smiling_face:
Hi @SonniTost π Thanks for reaching out. I've tried to reproduce your issue, but as you can see in the video below, I don't get the same error as you π€·ββοΈ
Can you help me figure out what I might be doing wrong? π
https://github.com/umbraco/Umbraco-CMS/assets/21998037/54df008f-9a73-4d77-9621-b14ede6a4559
Hi @elit0451
It seems that you can create a page and schedule it. But when you go to a scheduled page (after you have visited another page) the error occurs when you try to update the schedule.
I have tried to make a screen cast of the issue below.
https://github.com/umbraco/Umbraco-CMS/assets/66302306/46dea89d-d89b-4f79-8b54-d484a2971c62
Thanks for clarifying @SonniTost
I can indeed reproduce. I will mark it as up for grabs as we would like some help with it π
Hi @SonniTost,
We're writing to let you know that we would love some help with this issue. We feel that this issue is ideal to flag for a community member to work on it. Once flagged here, folk looking for issues to work on will know to look at yours. Of course, please feel free work on this yourself ;-). If there are any changes to this status, we'll be sure to let you know.
For more information about issues and states, have a look at this blog post.
Thanks muchly, from your friendly Umbraco GitHub bot :-)
Hi.
We are experiencing something related . In the "Info" tab, we can see that the "Created date" is displayed as "invalid date" when the CMS language is Danish here is the video:
Our version of the Umbraco is 11.4
https://github.com/umbraco/Umbraco-CMS/assets/15868547/0279fccc-3291-4da3-ac0e-bf921759274b
Just to add, I've tested the scheduled published in the latest Umbraco version, trying out all languages enabled for my user, and the only one I've had this issue with is Danish.
Great insight @emmagarland, thanks for that π
I am working on it :)
This is a frontend issue. Whenever there's already a date/time set for the scheduled publish and that date/time is not modified, the frontend is sending the time with . as unit separator instead of :
See screenshot below:
JSON posted by the frontend:
{
"id": 1059,
"contentTypeAlias": "contentPage",
"parentId": -1,
"action": "schedule",
"variants": [
{
"name": "Content created in danish (1)",
"properties": [
{
"id": 9,
"alias": "body",
"value": "<p>dummy</p>"
}
],
"culture": null,
"segment": null,
"publish": false,
"save": true,
"releaseDate": null,
"expireDate": "2023-06-23 13.25.00"
}
],
"expireDate": null,
"releaseDate": null,
"templateAlias": null
}
Notice the "13.25.00" in the expireDate vs the expected "13:25:00"
After further investigation, it seems that the time is being formatted in the backend in the response of the Get By Id API (/umbraco/backoffice/umbracoapi/content/GetById?id={node id}).
See the attached response examples in PT and in DA. Portuguese response example.txt
I figured out the issue.
In the JsonDateTimeFormatAttribute we are adding a IsoDateTimeConverter with a specific time format (the one expected by the frontend) but without specifying the culture. Whenever no culture is provided the IsoDateTimeConverter uses the CurrentCulture ("da-DK" in this case). In .Net (at least since Core 3.1), when you do a DateTime ToString("yyyy-MM-dd HH:mm:ss", new CultureInfo("da-DK")) it seems to replace the time separator symbols with the ones from the provided culture. In the case of the Danish culture it was replacing the : with .
There are a few more cultures that use . as the time separator but they are not available in the backoffice.
Created PR 14400 to fix this issue.
Created PR 14400 to fix this issue.
Amazing stuff!
Created PR 14400 to fix this issue.
Awesome work @miguelcrpinto I would need to find other issue to contribute to :)
For those interested in knowing more about this behavior, here's the official documentation from Microsoft.
Thanks @miguelcrpinto!
The related PR #14400 has now been merged. Thanks @SonniTost for raising this issue.
Best
Emma
@nul800sebastiaan this fix is super relevant for our client - but they are running on Umbraco 10. Could this be cherry picked for 10.6?
@SonniTost Yep I've cherry-picked it to the 10.6 release branch, so the fix will make it in π
Which Umbraco version are you using? (Please write the exact version, example: 10.1.0)
10.5.0
Bug summary
When users try to use the schedule function on a document - then the date format throws an Newtonsoft.Json error when the users press Schedule.
Specifics
It happens when the users' language is set to Danish. It seems that it does not happen when the users' language is set to English.
It could be related to this https://github.com/umbraco/Umbraco-CMS/issues/3075
Steps to reproduce
Open a page Instead of pressing Save and publish - click the arrow and select Schedule Set some dates and press Schedule.
https://github.com/umbraco/Umbraco-CMS/assets/66302306/b38316e1-8a4f-464c-8ce1-d5e567b873b7
Expected result / actual result
Expected
A schedule is created for the page (either publish or expire)
Actual
Throws a Newtonsoft.Json error - Could not convert string to DateTime: 2023-05-30 12.00.00. Path 'variants[0].releaseDate', line 1, position 8119. (Please note the . in the time format)
An error occurred Could not convert string to DateTime: 2023-05-30 12.00.00. Path 'variants[0].releaseDate', line 1, position 8119.
Undtagelsesdetaljer Newtonsoft.Json.JsonReaderException, Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed: Could not convert string to DateTime: 2023-05-30 12.00.00. Path 'variants[0].releaseDate', line 1, position 8119.
Stacktrace at Newtonsoft.Json.JsonReader.ReadDateTimeString(String s) at Newtonsoft.Json.JsonTextReader.FinishReadQuotedStringValue(ReadType readType) at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType) at Newtonsoft.Json.JsonTextReader.ReadAsDateTime() at Newtonsoft.Json.JsonReader.ReadForType(JsonContract contract, Boolean hasConverter) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at Umbraco.Cms.Web.BackOffice.ModelBinders.ContentModelBinderHelper.BindModelFromMultipartRequestAsync[T](IJsonSerializer jsonSerializer, IHostingEnvironment hostingEnvironment, ModelBindingContext bindingContext) at Umbraco.Cms.Web.BackOffice.ModelBinders.ContentItemBinder.BindModelAsync(ModelBindingContext bindingContext) at Microsoft.AspNetCore.Mvc.ModelBinding.Binders.BinderTypeModelBinder.BindModelAsync(ModelBindingContext bindingContext) at Microsoft.AspNetCore.Mvc.ModelBinding.ParameterBinder.BindModelAsync(ActionContext actionContext, IModelBinder modelBinder, IValueProvider valueProvider, ParameterDescriptor parameter, ModelMetadata metadata, Object value, Object container) at Microsoft.AspNetCore.Mvc.Controllers.ControllerBinderDelegateProvider.<>cDisplayClass0_0.<gBind|0>d.MoveNext()
--- End of stack trace from previous location ---
at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g Awaited|26_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)