为WCF序列化复杂对象

时间:2011-12-10 21:34:58

标签: c# wcf

我试图通过Windows Communication Foundation传递一个复杂的对象,但是我得到了Read错误。我能够将对象二进制格式化为文件并重新加载和反序列化。所有组件/引用的组件类都标有Seri​​alizable属性。作为一个工作循环,我已将对象序列化为内存流,通过WCF传递内存流,然后在另一端对内存流进行deSerialized。虽然我可以忍受这个解决方案,但它看起来并不是很整洁。我似乎无法确定能够从代理中读取的标准。相对简单的对象,甚至是包含对另一个类的引用的对象,可以在没有任何属性的情况下被传递和读取。欢迎任何建议。

编辑:无法识别错误109(0x6d)System.IO.IOException读取操作失败。

编辑在这里请求的是类和基类。它非常复杂,这就是为什么我在开始时没有包含代码,但二进制序列化很好。

[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);
    }
}

这里是基类:

[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);
    }
}

2 个答案:

答案 0 :(得分:3)

我建议您查看WCF中DataContracts的MSDN documentation,因为这提供了一些非常有用的指导。

<强>更新

根据提供的代码和异常信息,有两个值得怀疑的地方:

1)集合和字典,尤其是那些基于泛型的字典,总是给WCF客户端带来了困难,因为它不会将这两种类型的对象与它认为是相同的签名区分开来。但这通常会导致客户端出现反序列化错误,因此这可能不是您的问题。

如果这是您的问题,我已在我对this question的回答中列出了客户端的一些步骤。

2)您可以在层次结构中的某个位置拥有一个不可序列化的类。

如果您的WCF服务托管在IIS中,那么我找到的用于跟踪此类问题的最有价值的工具是内置的WCF记录器。要启用此日志记录,请将以下内容添加到主配置部分中的web.config文件中:

                                                       

生成错误后,双击svclog文件,将启动Microsoft Service Trace Viewer。左侧的红色项目是发生异常的地方,选择之后,您可以在右侧钻取其详细信息,它通常会告诉您哪个项目有问题。找到此工具后,追踪这些问题的时间从几小时到几分钟不等。

答案 1 :(得分:0)

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