0

I have a few columns that contain JSON data. These particular columns are an array of enums.

When querying the MembershipType table, the serialization and deserialization works well and as expected. However, I have a SQL view that nests an array of MembershipTypes and doing causes EF Core to throw an error similar to this:

System.Exception: "Error converting value \"[\"Certified\"]\" to type 'DataLayer.Models.Members.MembershipTypeCategory[]'. Path '[0].History.MembershipType.Categories', line 1, position 585."

You can see all the extra quotes and backslashes that are added to the value. I have tried string replacing the quotes and backslashes, which works, but this can have bad affects with other string data.

Any ideas?

Code below: SQL VIEW

SELECT 
    hist.*
    , (
        select * from Member.MembershipTypes 
        where id = hist.MembershipTypeId and Deleted = 0
        FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
    ) as MembershipType
...

Enum

public enum MembershipTypeCategory
{
    Type1,
    Type2,
    Type3
}

and the class it's on:

[Table("MembershipTypes", Schema = "Member")]
public class MembershipType : EntityBase, IMembershipTypeDto
{
    ...

    [NotMapped]
    public MembershipTypeCategory[] Categories { get; set; }
    
    ...
}

In the ModelBuilder I have:

var settings = new JsonSerializerSettings
{
    ContractResolver = new IgnoreVirtualResolver(),
    PreserveReferencesHandling = PreserveReferencesHandling.None,
    ReferenceLoopHandling = ReferenceLoopHandling.Ignore,
    TypeNameHandling = TypeNameHandling.All,
    Formatting = Formatting.None,
    Error = HandleDeserializationError
};

modelBuilder.Entity<MembershipType>()
    .Property(x => x.Categories)
    .HasConversion(
        v => JsonConvert.SerializeObject(v, Formatting.None, settings),
        v => JsonConvert.DeserializeObject<MembershipTypeCategory[]>(v, settings)
    );

return modelBuilder;
theblindprophet
  • 7,767
  • 5
  • 37
  • 55

1 Answers1

0

I think your converter is not ok. I generate code like your (in EF code first) and read/write data is ok, but string stored in db is:

{"$type":"XXX.Model.Tests.TestType[], XXX.Model","$values":[1,2]}

You have to think about converter again ;)

sample solution:

        public static string ToJson(Enum[] values)
        {
            return ((values?.Length ?? 0) == 0) ?  return "[]" : $"['{string.Join("','", values)}']";
        }

        public static Enum[] FromJson(string json)
        {
            return JsonConvert.DeserializeObject<Enum[]>(json);
        }

Or using methods from JavaScriptSerializer - JSON serialization of enum as string

kamaz08
  • 21
  • 1
  • 5