0

I filed a bug, but this seems like such a basic fundamental scenario that I must be missing something: Bug: https://github.com/dotnet/runtime/issues/48202

I am unable to Deserialize DateTime, Guid, or Enum with System.Text.Json.

Here is a very minimal XUnit test to repro how I would expect it to work, but is failing.

using System;
using System.Text.Json;
using Xunit;

namespace Example.Tests
{
    public class UnitTest1
    {
        [Fact]
        public void GuidsAndDateTimesNotSerialized()
        {
            var post = new Post {
                AuthorId = Guid.NewGuid(),
                Created = DateTime.UtcNow,
                Title = "test title",
                Path = "test-title",
                PostStatus = PostStatus.Published,
                Description = "this is a test",

            };
            var json = JsonSerializer.Serialize(post);
            var result = JsonSerializer.Deserialize<Post>(json);

            Assert.Equal(post.Created, result.Created);
            Assert.Equal(post.AuthorId, result.AuthorId);
            Assert.Equal(post.PostStatus, result.PostStatus);
        }
    }

    public class Post
    {
        public Guid AuthorId { get; internal set; }
        public string Title { get; set; }
        public string Path { get; set; }
        public string Description { get; set; }
        public PostStatus PostStatus { get; internal set; }
        public DateTime Created { get; internal set; }
    }

    public enum PostStatus
    {
        Draft,
        Published
    }
}

Is there something with using System.Text.Json that I am missing?

Matt Sanders
  • 953
  • 1
  • 13
  • 23

1 Answers1

3

My guess is your properties set with internal are not accessible to the JSON library/assembly. Simply change them to public (remove the internal access modifier) setters and try again.

JSON DTO's should be simple classes and always have a default constructor:

public class Post
{
    public Guid AuthorId { get; set; }
    public string Title { get; set; }
    public string Path { get; set; }
    public string Description { get; set; }
    public PostStatus PostStatus { get; set; }
    public DateTime Created { get; set; }
}
T McKeown
  • 12,971
  • 1
  • 25
  • 32
  • 1
    Tested, it is indeed the internal modifier on properties set. https://dotnetfiddle.net/G8K1fW – Leandro Requena Feb 12 '21 at 01:28
  • 1
    Thanks, it seems so obvious now! :P I don't usually have the internal set on my models and forgot I did that. I was trying to use the same model for my API for POST and GET and the internal was ignoring the internal sets on creation for my swagger docs. Now maybe back to the drawing board on that if I want to share these models between Api and Blazor projects :/ – Matt Sanders Feb 12 '21 at 01:35