-1

I have this class which deserializes the json of the object I receive so I can then put it into a class:

public CourseOverview CreateCourseOverview(object obj)
        {
            var instance = JsonConvert.DeserializeObject<CourseOverview>(obj.ToString());
            var courseOverview = new CourseOverview { CourseCode = instance.CourseCode, StartDate = instance.StartDate, Duration = instance.Duration, Title = instance.Title };
            Console.WriteLine(courseOverview);
            return courseOverview;
        }

The class it should be put into looks like this:

public class CourseOverview
    {
        [JsonConverter(typeof(CustomDateTimeConverter))]
        public DateTime StartDate { get; set; }
        public string Duration { get; set; }
        public string Title { get; set; }
        public string CourseCode { get; set; }
    }

The JsonConverter : CustomDateTimeConverter part I found on a different stackoverflow post. It however seems like it fails because it's expecting the first two characters to be the month (which cannot be > 12):

public class CustomDateTimeConverter : DateTimeConverterBase
    {
        private const string Format = "dd/MM/yyyy";

        public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        {
            writer.WriteValue(((DateTime)value).ToString(Format));
        }

        public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
        {
            if (reader.Value == null)
            {
                return null;
            }

            var s = reader.Value.ToString();
            DateTime result;
            if (DateTime.TryParseExact(s, Format, CultureInfo.InvariantCulture, DateTimeStyles.None, out result))
            {
                return result;
            }
            return null;
        }
    }

All works wonderful until I get a date like 15/10/2020, then it crashes with the message:
Newtonsoft.Json.JsonReaderException: Could not convert string to DateTime: 15/10/2020

Full error:

Reached? 1
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
      An unhandled exception has occurred while executing the request.
      Newtonsoft.Json.JsonReaderException: Could not convert string to DateTime: 18/10/2018. Path 'startDate', line 1, position 77.
         at Newtonsoft.Json.JsonReader.ReadDateTimeString(String s)
         at Newtonsoft.Json.JsonTextReader.ReadStringValue(ReadType readType)
         at Newtonsoft.Json.JsonTextReader.ReadAsDateTime()
         at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, 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.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 CourseEnv.Core.Factories.CourseFactory.CreateCourseOverview(Object obj) in C:\Users\pc\source\repos\CourseOverviewSln\CourseApp.Core\Factories\CourseFactory.cs:line 30
         at CourseApp.APIs.CourseAPI.AddCoursesFromFileAsync(Object[] objects) in C:\Users\pc\source\repos\CourseOverviewSln\CoursesApp\APIs\CourseAPI.cs:line 40
         at lambda_method5(Closure , Object )
         at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
      --- End of stack trace from previous location ---
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
         at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
         at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
         at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
         at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
dbc
  • 104,963
  • 20
  • 228
  • 340
CRS01
  • 37
  • 6
  • Can you show the exact JSON? The code you show here doesn't appear to show the issue you claim it does. At least, I cannot replicate it. – DavidG Sep 21 '22 at 08:53
  • 1
    Also, why do you create a new instance of `CourseOverview` instead of just returning the one you just deserialised? – DavidG Sep 21 '22 at 08:54
  • ValueKind = Object : "{"title":"Working","courseCode":"WKN","duration":"5","startDate":"18/10/2018"}" This is the value that's hold in the obj – CRS01 Sep 21 '22 at 08:59
  • Well I could just direct return the result from the JsonCovert indeed.. didn't even see that. Makes it way shorter, thanks for that! – CRS01 Sep 21 '22 at 09:01
  • It's working fine with your code: https://dotnetfiddle.net/4x6gAv – DavidG Sep 21 '22 at 09:07
  • The first two characters are somehow reviewed as if they were being the month number I just noticed... how could that be? – CRS01 Sep 21 '22 at 09:29
  • Your error suggests it is not using the `CustomDateTimeConverter`. Maybe you have multiple `CourseOverview` classes? – DavidG Sep 21 '22 at 09:30
  • Are you sure the `JsonConverter` attribute has been applied and used? If you remove it from the code I posted in the dotnetfiddle, then you will get the same error. – DavidG Sep 21 '22 at 09:42
  • I just changed the convert part to this: `var instance = JsonConvert.DeserializeObject(obj.ToString(), new IsoDateTimeConverter { DateTimeFormat = "dd/MM/yyyy" });` Now my dates work perfect.. until I have a date like 8/10/2020... so it's not accepting d/MM/yyyy then? – CRS01 Sep 21 '22 at 09:46
  • 1
    If your dates might contain a single character for day, then just use `d/MM/yyyy` – DavidG Sep 21 '22 at 09:48
  • I didn't know it'd be that easy... ;-) Alright, I'm all up and running now. Thanks for your time David! – CRS01 Sep 21 '22 at 09:50

1 Answers1

2

Changing the code to the code below did the trick:

return JsonConvert.DeserializeObject<CourseOverview>(obj.ToString(), new IsoDateTimeConverter { DateTimeFormat = "d/MM/yyyy" });
CRS01
  • 37
  • 6