我正在尝试与SalesForce中的SOAP Web服务集成。我的目标是简单地从SalesForce下拉用户数据,以便我们将其集成到我们的系统中。我能够使用从SalesForce网站上的合作伙伴WSDL生成的代理类(C#)成功登录。我要做的下一件事是查询用户,下拉FirstName,LastName,ect ......
重要的是要知道我被迫修改生成的代理代码,因为它生成错误。它填充xml序列化字段以匹配在进行Web服务调用时抛出异常的私有字段。它还为我删除的sObject类的“Any”属性生成了一个空白名称空间。如果你想知道为什么我做出这些选择,我会从this StackOverflow topic接受建议。
这是我的查询:
qResult正好包含3条记录(这是准确的,因为我只有3个用户)。问题是除了“type”之外,sObject上的每个属性都是null。
我无法确定在尝试查询时是否发生了一个简单的错误,或者我是否必须修改代理类并删除Any字段上的命名空间导致此问题。我不知道此时该怎么做。开发人员控制台(SalesForce.com)中的相同查询返回正确的数据。还值得一提的是,我的查询结果返回了适当数量的元素,它们只是没有任何数据。它必须是简单的东西......比如添加命名空间绑定,但要弄清楚应该是什么,或者在属性中添加xmlbinding。
我只是想知道是否有人知道该怎么做。也许某人发生了同样的事情?
编辑:所以我花时间执行一些令人难以置信的hacky技术来拦截来自生成的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;
}
答案 0 :(得分:1)
经过漫长的一天研究和挫折之后,我终于遇到了SalesForce的sObject类的“Any”属性的正确属性。 SalesForce试图将相关的xml元素扫描到这个sObject类中,这允许它们将sObject类保留为动态类型。因此,为了强制C#类将所有xml标记写入“Any”属性,我们只需应用它:
[System.Xml.Serialization.XmlAnyElement]
所以要明确的是,当您从SalesForce帐户生成WSDL时,它可能不是开箱即用的。您需要重命名一些传递给属性的字符串参数,并将sObject类的“Any”属性上的空命名空间替换为XmlAnyElement属性,以便从API的查询调用中获得成功的结果。可以在this StackOverflow topic主题中找到进行客户端功能所需的更改。
我现在能够成功调用SalesForce API的查询功能并返回我查询的字段......我感觉好多了!