Search Unity

BinaryFormatter, SerializationBinder not working

Discussion in 'Scripting' started by aer0ace, Jul 28, 2018.

  1. aer0ace

    aer0ace

    Joined:
    May 11, 2012
    Posts:
    1,513
    Has anyone had any luck using the SerializationBinder on a BinaryFormatter when deserializing their data?

    For the life of me, I can't figure out why my BindToType() is not hitting.

    I've changed my API Compatibility Level from .NET 2.0 Subset to .NET 2.0, because the breakpoints weren't hitting in the SerializationBinder constructor at all, but that part is now fixed.

    But I can't figure out why BindToType() is not getting called. I get an exception before the BinaryFormatter even attempts to try the binder.

    Code (csharp):
    1.  
    2. Could not find type 'System.Collections.Generic.List`1[[BoardData, Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]'.
    3.  
    That's the exception. BoardData is my type, and I've added a namespace so it should be namespace.BoardData, but I can't do that, because the BindToType() function is not running!

    Here is the code:
    Code (CSharp):
    1.             BoardPersistence board = new BoardPersistence();
    2.  
    3.             BinaryFormatter bf = new BinaryFormatter();
    4.  
    5.  
    6.             try
    7.             {
    8.                 bf.Binder = new NamespaceChangeDeserializationBinder();
    9.                 board = (BoardPersistence)bf.Deserialize(stream);
    10.             }
    11.             catch (SerializationException e)
    12.             {
    13.                 Dbg.Assert(false, e.Message);
    14.                 throw e;
    15.             }
    16.             catch (Exception e)
    17.             {
    18.                 throw e;
    19.             }
    And this is the SerializationBinder:
    Code (CSharp):
    1. sealed class NamespaceChangeDeserializationBinder : SerializationBinder
    2. {
    3.     public override Type BindToType(string assemblyName, string typeName)
    4.     {
    5.         typeName = "g106." + typeName;  // New Namespace
    6.  
    7.         return Type.GetType(string.Format("{0}, {1}", typeName, assemblyName));
    8.     }
    9. }
    And my persistence object
    Code (CSharp):
    1.  
    2. [System.Serializable]
    3. public class TileData
    4. {
    5.     public int TerrainType;
    6. }
    7.  
    8. [System.Serializable]
    9. public class BoardData
    10. {
    11.     public byte BoardId;
    12.  
    13.     public int Width;
    14.     public int Height;
    15.  
    16.     public List<TileData> Tiles = new List<TileData>();
    17. }
    18.  
    19.     [System.Serializable]
    20.     public class BoardPersistence : DataPersistence
    21.     {
    22.         public override void Write()
    23.         {
    24.             Version = 1;
    25.  
    26.  
    27.             Board[] boards = GameBoard.GetBoards();
    28.  
    29.             foreach (Board b in boards)
    30.             {
    31.                 BoardData data = WriteBoardData(b.BoardId, b);
    32.                 Boards.Add(data);
    33.             }
    34.         }
    35.  
    36.         private BoardData WriteBoardData(byte id, Board board)
    37.         {
    38.             BoardData boardData = new BoardData();
    39.  
    40.             boardData.BoardId = id;
    41.             boardData.Width = board.BoardWidth;
    42.             boardData.Height = board.BoardHeight;
    43.  
    44.             for (int h = 0; h < boardData.Height; ++h)
    45.             {
    46.                 for (int w = 0; w < boardData.Width; ++w)
    47.                 {
    48.                     GameTile tile = board.GetTileAtPoint(new RectPoint(w, h));
    49.                     TileData data = new TileData();
    50.  
    51.                     if (tile is TerrainTile)
    52.                         data.TerrainType = (int)(tile as TerrainTile).GetTerrainType();
    53.  
    54.                     boardData.Tiles.Add(data);
    55.                 }
    56.             }
    57.             return boardData;
    58.         }
    59.  
    60.         public override void Read()
    61.         {
    62.  
    63.             foreach (BoardData data in Boards)
    64.             {
    65.                 Board board = GameBoard.GetBoard(data.BoardId);
    66.                 board.BuildGrid(data.BoardId, data.Width, data.Height, data.Tiles);
    67.             }
    68.         }
    69.  
    70.         public List<BoardData> Boards = new List<BoardData>();
    71.     }
    Code (CSharp):
    1.     [System.Serializable]
    2.     abstract public class DataPersistence
    3.     {
    4.         abstract public void Write();
    5.  
    6.         abstract public void Read();
    7.  
    8.         public int Version = 0;
    9.     }
     
    Last edited: Jul 28, 2018