我需要使用C#SOAP API以编程方式将PDF文件上传到现有Salesforce记录。
我见过this question以及无数其他人,但是我发现的所有内容都没有解决我的问题,或者与另一种语言或REST API有关。我能够找到的所有C#SOAP API信息都使用附件对象,该对象似乎在API中不存在。我正在使用合作伙伴WSDL,并将其作为Web参考正确添加到我的项目中。
确实存在一个 EmailFileAttachment 对象,但是无法将其强制转换为 sObject 以保存到Salesforce记录中。
这是我当前拥有的代码,我可以更新数据字段。
// Login
var Binding = new SforceService();
var loginResult = Binding.login("Username", "Password");
Binding.Url = loginResult.serverUrl;
Binding.SessionHeaderValue = new SessionHeader();
Binding.SessionHeaderValue.sessionId = loginResult.sessionId;
// Create sObject, update data
var obj = new sObject();
obj.type = "tableName";
obj.Id = "objId";
var document = new XmlDocument();
var nodeList = new List<XmlElement>();
var dataNode = document.CreateElement("fieldName");
dataNode.InnerText = "fieldValue";
nodeList.Add(dataNode);
obj.Any = nodeList.ToArray();
// Save data
sObject[] objArray = { obj };
var saveResults = Binding.update(objArray);
但是我无法使用附件或 EmailFileAttachment 。我所知道的Salesforce API名称空间中没有附件。 EmailFileAttachment 具有我需要的所有正确字段,但是无法转换为 sObject ,所以我猜测它不是要使用的正确对象,或者我正在使用不正确。
// The type or namespace 'Attachment' could not be found.
//var attachment = new Attachment;
var attachment = new EmailFileAttachment();
attachment.id = "objId";
attachment.fileName = "filename.pdf";
attachment.body = fileData; // fileData is byte[]
// Cannot implicitely convert EmailFileAttachment to sObject.
var objArray = new sObject[] { attachment };
我是否缺少一些可以使用附件的东西,或者还有另一种方法可以做到这一点?
编辑:我正在使用Salesforce C#SOAP API v45.0
编辑:按照超跌的回答,我将文件作为sObject上传,效果很好。 唯一的规定是必须作为新的Salesforce对象创建附件,并通过 ParentId 字段将其链接到原始对象。 这是下面的工作代码
var atObj = new sObject();
// Set type as "Attachment"
atObj.type = "Attachment";
var document = new XmlDocument();
var nodeList = new List<XmlElement>();
// Set Filename
var nameNode = document.CreateElement("Name");
nameNode.InnerText = "testfile.pdf";
nodeList.Add(nameNode);
// Set ParentId - this is the object id you want to link the attachment to
var idNode = document.CreateElement("ParentId");
idNode.InnerText = "objId";
nodeList.Add(idNode);
// Set File Data - use Base64 string conversion
string encoded = Convert.ToBase64String(fileData); // fileData is byte[]
var dataNode = document.CreateElement("Body");
dataNode.InnerText = encoded;
nodeList.Add(dataNode);
atObj.Any = nodeList.ToArray();
sObject[] objArray = { atObj };
// Use create(), not update()
var saveResults = Binding.create(objArray);
答案 0 :(得分:1)
合作伙伴API仅包含通用SObject定义,没有具体的SObject类型。 (因为它期望合作伙伴希望只编写一次代码并使它动态适应用户模式)。您将需要为您的附件构建伙伴SObject实例,或者切换到将具有您要查找的具体Attachment类的企业WSDL。有关SObjects在伙伴API中的外观的详细信息,请参见[1]。在C#中有一个示例,用于合作伙伴API在[2]处创建一个SObject实例。您应该可以更改它以创建附件而不是联系人。
[1] https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_partner_objects.htm
[2] https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sample_create_call.htm#topic-title
答案 1 :(得分:0)
使用 Enterprise WSDL / SOAP 将文件 / ContentDocument 附加到我需要创建 ContentVersion 的对象,然后 Salesforce 创建 ContentDocument,然后创建 ContentDocumentLink 以将其附加到对象。
Byte[] bytes = File.ReadAllBytes(filePath);
ContentVersion cv = new ContentVersion();
cv.Title = Path.GetFileName(filePath);
cv.PathOnClient = filePath;
cv.VersionData = bytes;
cv.Origin = "H";
SaveResult[] createResults = _sfClient.create(new sObject[] { cv });
if (createResults.Count() > 0 && createResults[0].success)
{
cv.Id = createResults[0].id;
QueryResult queryResult = _sfClient.query(string.Format("select Id, ContentDocumentId from ContentVersion where Id = '{0}'", cv.Id));
if (queryResult.records == null) return null;
sObject[] records = queryResult.records;
//we can loop through the returned records
if (records.Length > 0)
{
List<ContentVersion> cvs = new List<ContentVersion>(queryResult.records.Cast<ContentVersion>());
ContentDocumentLink contentLink = new ContentDocumentLink();
contentLink.LinkedEntityId = sfCase.Id;
contentLink.ContentDocumentId = cvs.First().ContentDocumentId;
contentLink.ShareType = "V";
contentLink.IsDeleted = false;
SaveResult[] createResults1 = _sfClient.create(new sObject[] { contentLink });
if (createResults1.Count() > 0 && createResults1[0].success)
{
return createResults1[0].id;
}
else if (createResults1.Count() > 0)
{
return "Error. Case Content Document Failed. Case Number: [" + Helpers.Trim(sfCase.Case_Number__c) + "] had an error inserting. The error reported was: " + createResults1[0].errors[0].message;
}
}
}
else if (createResults.Count() > 0)
{
return "Error. Case Content Version Failed. Case Number: [" + Helpers.Trim(sfCase.Case_Number__c) + "] had an error inserting. The error reported was: " + createResults[0].errors[0].message;
}
}
catch (Exception ex)
{
return string.Format("Upsert {0}", ex.Message);
}