0

We have been using .NET Core 3.1 to serialize/deserialize with this code:

public UserData Clone()
{
    return ((ICloneable)this).Clone() as UserData;
}

object ICloneable.Clone()
{
    BinaryFormatter binary = new BinaryFormatter();

    using (var ms = new MemoryStream())
    {
        binary.Serialize(ms, this);
        ms.Flush();
        ms.Position = 0;
        return binary.Deserialize(ms);
    }
}

var filteredData = records.Clone();

But with the upgrade to .NET 6, the following code throws an error:

BinaryFormatter serialization & deserialization are disabled within the application

I tried to update the code as below using JsonSerializer as below:

JsonSerializer serializer = new JsonSerializer();

using (var ms = new MemoryStream())
{
    var jsonTextWriter = new JsonTextWriter(new StreamWriter(ms));
    Serialize the object to JSON and write it to the MemoryStream.
    serializer.Serialize(jsonTextWriter, this);
    ms.Flush();
    ms.Position = 0;
    var jsonTextReader = new JsonTextReader(new StreamReader(ms));
    return serializer.Deserialize<object>(jsonTextReader);
}

Above code builds fine, but when called, filteredData returns null:

var filteredData = records.Clone();

I am not sure if I am using this in a correct way or something is missing. Could anyone provide their inputs? Thanks

//Updated with new code

  object ICloneable.Clone()
        {
            var serialized = JsonConvert.SerializeObject(this);
            return JsonConvert.DeserializeObject<UserData>(serialized);
        }
Brenda
  • 510
  • 3
  • 13
  • 36
  • Specify the concrete type and not `object` as type parameter or function argument in Deserialize. – NineBerry Mar 03 '23 at 02:15
  • You mean like this? return serializer.Deserialize(jsonTextReader); This also returns null – Brenda Mar 03 '23 at 02:21
  • Please provide a [mcve] that includes the declaration of the type UserData or another type that reproduces the problem – NineBerry Mar 03 '23 at 15:31

1 Answers1

0

You don't need to mix JsonSerializer und JsonTextWriter. Just use JsonSerializer from .net:

object ICloneable.Clone()
{
    using (var ms = new MemoryStream())
    {
        JsonSerializer.Serialize(ms, this);
        ms.Position = 0;
        return JsonSerializer.Deserialize(ms, this.GetType());
    }
}

Full sample code:

using System.Text.Json;

namespace ConsoleApp33
{
    internal class Program
    {
        static void Main(string[] args)
        {
            UserData d = new UserData { Id = 42, Name = "Test" };
            UserData e = d.Clone();

            Console.WriteLine("Result: " + e.Id + " " + e.Name);
            Console.ReadLine(); 
        }
    }

    public class UserData: ICloneable 
    { 
        public int Id { get; set; }
        public string Name { get; set; }

        public UserData Clone()
        {
            return ((ICloneable)this).Clone() as UserData;
        }

        object ICloneable.Clone()
        {
            using (var ms = new MemoryStream())
            {
                JsonSerializer.Serialize(ms, this);
                ms.Position = 0;
                return JsonSerializer.Deserialize(ms, this.GetType());
            }
        }
    }
}

Please note that using this mechanism only public properties are copied and that if there are setters for the properties, these are run during de-serializing. If you want to include fields, see the documentation.

The BinaryFormatter did actually serialize and de-serialize the fields of the object, not its properties.

NineBerry
  • 26,306
  • 3
  • 62
  • 93
  • I was using NewtonSoft.Json. But now when I switch to System.Text.Json with your above code it throws the error as: "Deserialization of interface types is not supported" Looks like my data is complex type and is not able to handle using System.Text.Json – Brenda Mar 03 '23 at 02:42
  • Please provide a [mcve] – NineBerry Mar 03 '23 at 02:44
  • There is another question on how to serialize and deserialize objects with interface properties using Json: https://stackoverflow.com/questions/5780888/casting-interfaces-for-deserialization-in-json-net – NineBerry Mar 03 '23 at 02:45
  • I will check the above article and see how this can be implemented. Not sure why Microsoft when updating versions make things so difficult. A version upgrade should be simple and not break existing things. Here they mentioned to use JsonSerilizer but dont give any examples on how things should be done. https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/5.0/binaryformatter-serialization-obsolete – Brenda Mar 03 '23 at 02:51
  • I have updated the code above, see under new code. Do you see any issues in this. – Brenda Mar 03 '23 at 13:44