【问题标题】:Losing collection objects that are passed to a web service as properties of another object丢失作为另一个对象的属性传递给 Web 服务的集合对象
【发布时间】:2014-01-08 12:10:30
【问题描述】:

我必须开发一个非常复杂的 ASP.Net Web 服务。以下是我编写的示例代码。

首先,我有一个以 List 作为参数的 Web 服务方法。

[WebMethod] public AppResults SyncObjectToServer(string appID, List updates)

WSExecCommand 是我定义的一个包含多个 List 对象的类。这是WSExecCommand 的简化版本。

[Serializable] public class WSExecCommand
{
    public string Command;

    [XmlIgnore] public Dictionary<string, MyKeyValuePair> __ParentKey;
    [XmlArray] public List<MyKeyValuePair> ParentKey
    { 
        get
        {
            if (__ParentKey == null)
                __ParentKey = new Dictionary<string, MyKeyValuePair>;
            return new List<KeyValuePair>(__ParentKey.Values); 
        }
        set
        {
            __ParentKey.Clear();
            foreach (MyKeyValuePair kvp in value)
                __ParentKey.Add(kvp.Key, kvp);
        }
    }
}

如果你想知道我为什么要这样设置我的类,问题是 ASP.Net 不允许你返回或接收 Dictionary 对象。我真的需要将我的 ParentKey 对象作为字典。但是,为了绕过 ASP.Net 的限制,我创建了上述包装器属性来获取和设置底层 Dictionary 的值,我在代码中引用了它。

我的问题是,当我从我的消费应用程序调用我的 Web 服务方法时,__ParentKey 永远不会填充传递给服务器的数据。

我已经进入了 Web 服务代码,我得到了一个填充的 List&lt;WSExecCommand&gt; 集合。但是,对于列表中的每个WSExecCommand,所有List&lt;T&gt; 类型的对象都有0 个项目。

我该如何解决这个问题?

【问题讨论】:

    标签: c# asp.net .net web-services collections


    【解决方案1】:
    get
    {
        if (__ParentKey == null)
            __ParentKey = new Dictionary<string, MyKeyValuePair>;
        return new List<KeyValuePair>(__ParentKey.Values); 
    }
    

    看起来你在这里将 __ParentKey 设置为一个新的字典,然后返回该字典中的 KeyValuePairs 列表,当你第一次调用它时它当然是空的。由于您选择不序列化__ParentKey(无论如何您都不能序列化,因为字典不可序列化),当WSExecCommand 的实例在线路的另一端反序列化时,__ParentKey 为空(这会在您第一次尝试访问该属性时导致一个空列表)。

    编辑

    可能会像您期望的那样在反序列化时调用 setter。但是,如果是这种情况,那么您的问题很可能是 __ParentKey 在您构造对象时为空,并且在您第一次调用 getter 之前不会被实例化。我不相信在反序列化期间会调用您的 getter,因此永远不会创建您的字典实例。尝试预先构建你的字典,这样你也可以从你的 getter 中删除 null 检查。

    [Serializable] public class WSExecCommand
    {
        public string Command;
    
        [XmlIgnore] public Dictionary<string, MyKeyValuePair> __ParentKey = 
             new Dictionary<string, MyKeyValuePair>();
        [XmlArray] public List<MyKeyValuePair> ParentKey
        { 
            get
            {
                return new List<KeyValuePair>(__ParentKey.Values); 
            }
            set
            {
                __ParentKey.Clear();
                foreach (MyKeyValuePair kvp in value)
                    __ParentKey.Add(kvp.Key, kvp);
            }
        }
    }
    

    【讨论】:

    • 嘿,迈克,我实际上添加了 __ParentKey 空检查,因为否则,.Net 中出现了问题。我无法从我的测试用例中进入我的 Web 服务。我不确定 ASP.Net 如何接受 XML 请求并将它们转换为适当的类型。但是,我添加了空检查,以便字典存在。你知道我该如何解决这个难题吗?!
    • 它在 .NET 中没有损坏。当您将 __ParentKey 的值发送到服务或从服务发送时,您没有序列化它的值,因此在另一端它始终为空。就像我在回答中所说的那样,由于您无法序列化Dictionary,因此您必须想出另一种方法来将所需的数据放入可序列化的字段中,以便可以通过网络传输。从那里你可以做任何你需要的工作,把它从中间格式恢复到你想要的Dictionary
    • 对不起,如果我看起来很密集,但这首先是 List 属性的目的。我可以在我的测试控制台应用程序中从我的自动生成的类中看到这个列表对象。我的假设是,一旦 ASP.Net 反序列化了我的 XML 请求,它就会将我的 XML 数组转换为 List 并尝试通过设置器对其进行设置。然后,setter 代码将初始化 Dictionary。当然,我可以尝试找到一种不同的方式来做到这一点。然而,我的方法对我来说是合乎逻辑的。
    • 有可能,我更习惯于 WCF 的 DataContract 序列化而不是 XML 序列化。从接收应用程序(您要发送此对象的应用程序不是从该应用程序)在设置器中放置一个断点,并让我知道在反序列化过程中是否被击中。还要看看你是否能弄清楚它设置的value 是什么。如果它是一个空列表,那么您就会知道它在原始序列化中丢失了
    • 嘿,迈克 C,我给你答案是因为这确实帮助我解决了问题,尽管不是以我喜欢的方式。无论如何,我实例化 __ParentKey 的原因是因为当我在 getter 和 setter 上设置断点时,总是先访问 getter,然后再访问 setter。所以,我的想法是,实例化 getter,然后,任何设置或添加到列表的调用都应该自动工作。可能有办法解决这个问题,但我已经继续前进了。感谢您建议尝试不同的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-26
    • 1970-01-01
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多