4

我正在尝试与 SalesForce 的 SOAP Web 服务集成。我的目标是简单地从 SalesForce 中提取用户数据,以便我们可以将其集成到我们的系统中。我能够使用从 SalesForce 网站上的合作伙伴 WSDL 生成的代理类 (C#) 成功登录。我要做的下一件事是查询用户,下拉名字、姓氏等...

重要的是要知道我被迫修改生成的代理代码,因为它生成不正确。它填充了 xml 序列化字段以匹配在进行 Web 服务调用时引发异常的私有字段。它还为我删除的 sObject 类的“Any”属性生成了一个空白命名空间。如果您想了解我做出这些选择的原因,我从这个 StackOverflow 主题中获得了建议。

这是我的查询的样子: 在此处输入图像描述

qResult 正好包含 3 条记录(这是准确的,因为我只有 3 个用户)。问题是 sObject 上的每个属性除了“类型”之外总是为空。

我不知道是在尝试查询时犯了一个简单的错误,还是我必须修改代理类并删除 Any 字段上的命名空间这一事实导致了这个问题。我现在不知道该怎么做。开发人员控制台(SalesForce.com)中的相同查询返回正确的数据。还值得一提的是,我的查询结果返回了适量的元素,它们只是没有任何数据。它一定很简单......就像添加命名空间绑定但弄清楚它应该是什么或向属性添加 xmlbinding。

我只是想知道是否有人知道该怎么做。也许有人也有同样的事情发生在他们身上?

编辑:所以我花时间执行一些令人难以置信的黑客技术来拦截来自生成的 Web 服务客户端的请求,最后我得到了从 SalesForce 发送来响应我的请求的原始数据。这里是:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
    <soapenv:Body>
        <queryResponse>
            <result xsi:type="QueryResult">
            <done>true</done>
            <queryLocator xsi:nil="true"/>
            <records xsi:type="sf:sObject">
                <sf:type>User</sf:type>
                <sf:Id xsi:nil="true"/>
                <sf:FirstName>Bob</sf:FirstName>
                <sf:LastName>Dyllan</sf:LastName>
                <sf:Email>bob@bob.com</sf:Email>
                <sf:CompanyName xsi:nil="true"/>
                <sf:Phone xsi:nil="true"/>
                <sf:Title xsi:nil="true"/>
            </records>
            <records xsi:type="sf:sObject">
                <sf:type>User</sf:type>
                <sf:Id xsi:nil="true"/>
                <sf:FirstName>Zachary</sf:FirstName>
                <sf:LastName>Sheppard</sf:LastName>
                <sf:Email>some_guy@yahoo.com</sf:Email>
                <sf:CompanyName>Yahoo</sf:CompanyName>
                <sf:Phone xsi:nil="true"/>  
                <sf:Title xsi:nil="true"/>
            </records>
            <records xsi:type="sf:sObject"> 
                <sf:type>User</sf:type>
                <sf:Id xsi:nil="true"/>
                <sf:FirstName xsi:nil="true"/>
                <sf:LastName>Chatter Expert</sf:LastName>   
                <sf:Email>noreply@chatter.salesforce.com</sf:Email>
                <sf:CompanyName xsi:nil="true"/>        
                <sf:Phone xsi:nil="true"/>
                <sf:Title xsi:nil="true"/>
            </records>
            <size>3</size>
            </result>
        </queryResponse>
    </soapenv:Body>
    </soapenv:Envelope>

这些 sObjects 上的“sf”属性似乎确实存在序列化问题......但我如何使它与我的 C# 匹配?这是当前用于 sObject 类的 C#:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:sobject.partner.soap.sforce.com")]
public partial class sObject
{

    /// <remarks/>
    public string type;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("fieldsToNull", IsNullable=true)]
    public string[]
        fieldsToNull;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
    public string
        Id;

    /// <remarks/>
    public System.Xml.XmlElement[]
        Any;
}
4

1 回答 1

1

经过一整天的研究和挫折,我终于找到了 SalesForce 的 sObject 类的“任何”属性的正确属性。SalesForce 试图将相关的 xml 元素收集到这个 sObject 类中,这允许他们将 sObject 类保留为动态类型。因此,为了强制 C# 类将所有 xml 标记刮入“Any”属性中,我们只需应用以下代码:

[System.Xml.Serialization.XmlAnyElement]

需要明确的是,当您从您的 SalesForce 帐户生成 WSDL 时,它可能不正确。您需要重命名传递给属性的一些字符串参数,并将 sObject 类的“Any”属性上的空命名空间替换为 XmlAnyElement 属性,以便从 API 的查询调用中获得成功的结果。可以在此 StackOverflow 主题主题中找到使客户端功能所需的更改。

我现在能够成功调用 SalesForce API 的查询函数并取回我查询的字段......我感觉好多了!

于 2012-10-19T15:24:41.613 回答