简体   繁体   中英

Serializing complex objects for WCF

I'm trying to pass a complex object via Windows Communication Foundation, but I get Read errors. I'm able to binaryFormat the object to a file and reload and deserialize it. All the components/ referenced component Classes are marked with the Serializable attribute. As a work round I have serialized the object to a memory stream, passed the memory stream over WCF and then deSerialized the memory stream at the other end. Although I could live with this solution it doesn't seem very neat. I can't seem to work out what the criteria are for being able to read from the proxy. Relatively simple objects, even ones that include a reference to another class can be be passed and read without any attribute at all. Any advice welcomed.

Edit: Unrecognised error 109 (0x6d) System.IO.IOException the Read Operation Failed.

Edited As Requested here's the class and the base class. Its pretty complicated that's why I didn't include code at the start, but it binary serializes fine.

[Serializable]
public class View : Descrip
{
    //MsgSentCoreDel msgHandler;
    public Charac playerCharac { get; internal set;}
    KeyList<UnitV> unitVs;        
    public override IReadList<Unit> units { get { return unitVs; } }
    public View(Scen scen, Charac playerCharacI /* , MsgSentCoreDel msgHandlerI */)
    {
        playerCharac = playerCharacI;
        //msgHandler = msgHandlerI;
        DateTime dateTimeI = scen.dateTime;
        polities = new PolityList(this, scen.polities);
        characs = new CharacList(this, scen.characs);            
        unitVs = new KeyList<UnitV>();
        scen.unitCs.ForEach(i => unitVs.Add(new UnitV(this, i)));
        if (scen.map is MapFlat)                           
            map = new MapFlat(this, scen.map as MapFlat);            
        else            
            throw new Exception("Unknown map type in View constructor");            
        map.Copy(scen.map);        
    }

    public void SendMsg(MsgCore msg)
    {
        msg.dateT = dateTime;
        //msgHandler(msg);
    }
}

And here's the base class:

[Serializable]
public abstract class Descrip
{
    public DateTime dateTime { get; set; }        
    public MapStrat map { get; set; }       


    public CharacList characs { get; protected set; }
    public PolityList polities { get; protected set; }
    public abstract IReadList<Unit> units { get; }
    public GridElList<Hex> hexs { get { return map.hexs; } }
    public GridElList<HexSide> sides { get { return map.sides; } }
    public Polity noPolity { get { return polities.none; } }
    public double hexScale {get { return map.HexScale;}} 

    protected Descrip ()
    {                                   
    }

    public MapArea newMapArea()
    {
        return new MapArea(this, true);
    }
}

I suggest that you take a look at the MSDN documentation for DataContracts in WCF since that provides some very helpful guidance.

Update

Based on the provided code and exception information, there are two areas of suspicion:

1) Collections and Dictionaries, especially those that are generics-based, always give the WCF client a hard time since it will not differentiate between two of these types of objects with what it considers to be the same signature. This will usually result in a deserialization error on the client, though, so this may not be your problem.

If it is your problem, I have outlined some of the steps to take on the client in my answer to this question .

2) You could have, somewhere in your hierarchy, an class that is not serializable.

If your WCF service is hosted in IIS, then the most invaluable tool that I have found for tracking down this kind of issue is the built-in WCF logger. To enable this logging, add the following to your web.config file in the main configuration section:

After you have generated the error, double-click on the svclog file and the Microsoft Service Trace Viewer will be launched. The items in red on the left-hand side are where exceptions occur and after selecting one, you can drill into its detail on the right hand side and it usually tells you exactly which item it had a problem with. Once we found this tool, tracking down these issues went from hours to minutes.

您应该使用DataContractDataMember属性来明确说明WCF应该序列化哪些字段,否则还应实现ISerializable并自己编写(反)序列化。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM