Geras1mleo / Chess

C# .NET 6.0 Chess Library
MIT License
49 stars 15 forks source link

Chess.ChessBoard Deserialization exception #7

Closed manushand closed 1 year ago

manushand commented 1 year ago

Describe the bug When using Newtonsoft.Json to Deserialize a ChessBoard object, I get the following exception: Newtonsoft.Json.JsonSerializationException: 'Error setting value to 'MoveIndex' on 'Chess.ChessBoard'. with the Inner Exception being: IndexOutOfRangeException: Move not found

I get this when executing this line of my code: JsonConvert.DeserializeObject<T>(value); where value is an instance of type T : Solver and Solver is a class that contains this serialized field:

    [JsonProperty]
    private readonly Dictionary<string, MyPosition> _savedPositions = new ();

and MyPosition is a sealed record that contains this serialized field: public ChessBoard Board { get; set; }

To Reproduce

sealed record MyPosition
{
    public ChessBoard Board { get; set; } = new ();

        // Actually, since the error involves MoveIndex and the Move class, it may be that
        // one or more Moves may need to be made on the Board in order to get it into a
        // state where the Deserialization exception happens??  I do not know, but it is
        // certainly the case that one or more moves were indeed made on the Boards I
        // am trying to Serialize/Deserialize.
}
class Solver
{
    [JsonProperty]
    private readonly Dictionary<string, MyPosition> _savedPositions = new () { ["test"] = new () };
}
...
var serialized = JsonConvert.SerializeObject(new Solver());
var deserialized = JsonConvert.DeserializeObject<Solver>(serialized);

Expected behaviour The object should deserialize.

Screenshots N/A

Additional context N/A

Geras1mleo commented 1 year ago

Hi there!

In this version you can't just put moves inside ChessBoard object (primarily for encapsulation) when trying to deserialize board. If you look at ExecutedMoves you will see that this property has only a "getter" and can't be populated from the outside. To recreate ChessBoard object you will have to redo all moves using provided methods. So JsonConvert.DeserializeObject tries to set a MoveIndex of move that never existed on a newly created board...

You can fork the lib, make some properties virtual and override them depending to your needs. Feel free to open more issues if you have questions/remarks about this chess lib.

manushand commented 1 year ago

Thank you for your response. I found a different way of doing what I needed but I truly appreciate your replying.

On Sat, Dec 17, 2022 at 6:13 PM Sviatoslav @.***> wrote:

Hi there!

In this version you can't just put moves inside ChessBoard object (primarily for encapsulation) when trying to deserialize board. If you look at ExecutedMoves https://github.com/Geras1mleo/Chess/blob/master/ChessLibrary/ChessBoard/ChessBoard.cs#L175 you will see that this property has only a "getter" and can't be populated from the outside. To recreate ChessBoard object you will have to redo all moves using provided methods. So JsonConvert.DeserializeObject tries to set a MoveIndex of move that never existed on a newly created board...

You can fork the lib, make some properties virtual and override them depending to your needs. Feel free to open more issues if you have questions/remarks about this chess lib.

— Reply to this email directly, view it on GitHub https://github.com/Geras1mleo/Chess/issues/7#issuecomment-1356610037, or unsubscribe https://github.com/notifications/unsubscribe-auth/ASF4VN54K2RLH2OPBKMPWY3WNZQH7ANCNFSM6AAAAAASVY5UAY . You are receiving this because you authored the thread.Message ID: @.***>