Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C#: The input stream is not a valid binary format

I have a problem with deserializing in C#/ASP.NET, which gives the exact error:

The input stream is not a valid binary format. The starting contents (in bytes) are: 41-41-45-41-41-41-44-2F-2F-2F-2F-2F-41-51-41-41-41 ...

What I am trying to do

I have a structure with 3 classes. I have a class A which is a base class, and then class B and C which are derived from A.

I am trying to store random types of B and C in the database using LINQ to SQL, in a column with the type VARCHAR(MAX). I cannot use BINARY as the length is around 15.000.

My code...

Error is in the LAST codeblock

C# Code in Business layer- Storing a record

    private void AddTraceToDatabase(FightTrace trace)
    {
        MemoryStream recieverStream = new MemoryStream();
        MemoryStream firedStream = new MemoryStream();
        MemoryStream moveStream = new MemoryStream();

        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(recieverStream,trace.Reciever);
        binaryFormatter.Serialize(firedStream,trace.FiredBy);
        binaryFormatter.Serialize(moveStream,trace.Move);

        string reciever = Convert.ToBase64String(recieverStream.ToArray());
        string fired = Convert.ToBase64String(firedStream.ToArray());
        string move = Convert.ToBase64String(moveStream.ToArray());


        this.dataAccess.AddFightTrace(trace.TraceType.ToString(),reciever,move,fired,trace.DateTime,this.FightId);
    }

C# Code in Data access layer - Storing a record

    public void AddFightTrace(string type, string reciever, string Move, string firedBy, DateTime firedAt, int fightid)
    {
        GameDataContext db = new GameDataContext();
        dbFightTrace trace = new dbFightTrace();
        trace.TraceType = type;

        trace.Reciever = reciever;
        trace.Move = Move;
        trace.FiredBy = firedBy;
        trace.FiredAt = firedAt;
        trace.FightId = fightid;

        db.dbFightTraces.InsertOnSubmit(trace);
        db.SubmitChanges();
    }

C# Code getting the entry in the database

    public List<dbFightTrace> GetNewTraces(int fightid, DateTime lastUpdate)
    {
        GameDataContext db = new GameDataContext();
        var data = from d in db.dbFightTraces
                   where d.FightId==fightid && d.FiredAt > lastUpdate
                   select d;

        return data.ToList();
    }

C# Factory, converting from LINQ to SQL class to my objects

THIS IS HERE THE ERROR COMES

    public FightTrace CreateTrace(dbFightTrace trace)
    {
        TraceType traceType = (TraceType) Enum.Parse(typeof(TraceType), trace.TraceType);
        BinaryFormatter formatter = new BinaryFormatter();

        System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();

        MemoryStream recieverStream = new MemoryStream(enc.GetBytes(trace.Reciever));
        recieverStream.Position = 0;
        MemoryStream firedStream = new MemoryStream(enc.GetBytes(trace.FiredBy));
        firedStream.Position = 0;
        MemoryStream movedStream = new MemoryStream(enc.GetBytes(trace.Move));
        movedStream.Position = 0;

        // THE NEXT LINE HERE CAUSES THE ERROR
        NPC reciever = formatter.Deserialize(recieverStream) as NPC;
        Player fired = formatter.Deserialize(firedStream) as Player;
        BaseAttack attack = formatter.Deserialize(movedStream) as BaseAttack;

        FightTrace t = new FightTrace(traceType,reciever,attack,fired);
        t.TraceId = trace.FightTraceId;
        t.DateTime = trace.FiredAt;
        return t;
    }

So the error happends when the first Deserialize method is run, with the above error.

I have tried several things but I am quite lost on this one..

Thanks! :-)

like image 460
Lars Holdgaard Avatar asked Feb 03 '11 15:02

Lars Holdgaard


2 Answers

I think the coversion back from base64 to bytes is wrong.

Try this:

var bytes = Convert.FromBase64String(base64);

=>

 MemoryStream recieverStream = new MemoryStream(Convert.FromBase64String(trace.Reciever));

  NPC reciever = formatter.Deserialize(recieverStream) as NPC;
like image 122
CaptainPlanet Avatar answered Sep 22 '22 11:09

CaptainPlanet


I think it is because Convert.ToBase64String(recieverStream.ToArray()) and enc.GetBytes(trace.Reciever) are not each other counterparts.

You need do unencode the base64 in the decoding part.

like image 43
Henk Holterman Avatar answered Sep 20 '22 11:09

Henk Holterman