DateTimeOffset stored as ISO 8601 string in JobDataMap is discarded when executing the job
See original GitHub issueVersion: 3.0.7
- dotnetcore 3.1.200
Expected behavior
When storing a DateTimeOffset
(ISO 8601) string in the JobDataMap
and having it serialised into a ADO Store. I expect to be able to retrieve the DateTimeOffset
from the job context when the job executes.
The following config is set (as well as the ADO store details):
quartz.jobStore.useProperties = true
quartz.serializer.type = json
Actual behavior
I am unable to get the DateTimeOffset
(ISO 8601) string from the MergedJobDataMap
associated with the job execution context. I need to prefix the string value with something else to be able to retrieve it. It is stored in the database, but when pulling it into the executing job it’s not there.
My shot in the dark guess is that the deserialiser is picking up that the string is a DateTimeOffset
and is thus deserialising it into that type whereas JobDataMap is expecting all values to be strings (due to the useProperties
config) and quietly discards anything which is not.
Steps to reproduce
- Set the
quartz.jobStore.useProperties = true
value in config - Set the
quartz.serializer.type = json
value in config - Create a new job/trigger with at least one
DateTimeOffset
stored as a string using the ISO 8601 format.
var job = JobBuilder.Create<ExampleJob>()
.WithIdentity("Example", group)
.UsingJobData("executed_at", DateTimeOffset.Now.ToString("O"))
.Build();
var jobTrigger = TriggerBuilder.Create()
.WithIdentity("ExampleTrigger", group)
.StartNow()
.Build();
- Now schedule the job. When it gets executed the
IJobExecutionContext
will not have theexecuted_at
property defined in theMergedJobDataMap
.
If I store the DateTimeOffset like this, then I can retrieve it as a string and parse it myself:
.UsingJobData("executed_at", $"{nameof(DateTimeOffset)}:{DateTimeOffset.Now:O}")
Issue Analytics
- State:
- Created 4 years ago
- Comments:5 (3 by maintainers)
Top GitHub Comments
Hey @dmk99 If you want to use the fix for this now, you can use the preview/nightly version of the library which can be found at this MyGet Feed
If this doesn’t fix your issue then let me know and I’ll try to see why if I can 👍
I believe
quartz.jobStore.useProperties = true
instructs Quartz to store and retrieve all values as strings instead of trying to serialize and deserialize the object (see code below). The reason this is the recommended option is that it is unlikely to break when Quartz knows all values are simple strings, but I think it is also safe to use primitive types and have this option set tofalse
. As long as you avoid using classes then you’ll probably be safe.https://github.com/quartznet/quartznet/blob/b76e6fa5f03d333b94be00f829493dca3f2480d8/src/Quartz/Impl/AdoJobStore/StdAdoDelegate.cs#L3254-L3256