Ошибка синтаксического анализа XML - Salesforce Bulk API с использованием C # - PullRequest
1 голос
/ 31 января 2012

Я пытаюсь Создать задание и Добавить пакет , используя Salesforce Bulk API, но я получаю XML Parsing Error обратно от Salesforce.

Как указано в вопросе Подключение к SalesForce API с использованием C # , я использую партнерский WSDL для выполнения входа;это и вызов Create Job работают.(До того, как я попытался выполнить вход с помощью POSTing XML, как упоминалось в документации ; я тоже не мог заставить это работать.)

К сожалению, я немного заржавелс C #, но вот код, с которым я работаю.

...
using SalesforceTest.sforce;
...

namespace SalesforceTest
{
    public partial class InvokeBulkAPI : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e) { }

        public string SalesforceLogin(string username, string password)
        {
            SforceService binding = new SforceService();
            binding.Timeout = 60000;

            try
            {
                LoginResult lr = binding.login(username, password);
                binding.Url = lr.serverUrl;

                return lr.sessionId;
            }
            catch (SoapException e) { return e.Message; }
        }

        public string CreateJob(string sfSessionId, string sfOperation, string sfObjectName)
        {
            string str = "";
            string reqURL = "";

            byte[] bytes;

            XmlDocument reqDoc;
            XmlDocument respDoc;

            str = ""
                + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" // added \r\n as recommended by L.B's answer
                + "<jobInfo xmlns=\"http://www.force.com/2009/06/asyncapi/dataload\">"
                + "    <operation></operation>" // removed "+sfOperation+"
                + "    <object></object>" // removed "+sfObjectName+"
                + "    <contentType>XML</contentType>" // should be CSV, NOT XML
                + "</jobInfo>"
            ;

            reqURL = "https://cs12-api.salesforce.com/services/async/23.0/job";
            reqDoc = new XmlDocument(); 
            reqDoc.LoadXml(str);

            // added XML modifications
            reqDoc.GetElementsByTagName("operation")[0].InnerText = sfOperation;
            reqDoc.GetElementsByTagName("object")[0].InnerText = sfObjectName;

            bytes = System.Text.Encoding.ASCII.GetBytes(reqDoc.InnerXml);
            respDoc = Post(bytes, reqURL, sfSessionId); // create job

            string JobId = (respDoc != null) ? 
                (respDoc.GetElementsByTagName("id").Count > 0) ?
                    (respDoc.GetElementsByTagName("id")[0].InnerText) :
                    "" :
                ""
            ;

            return JobId;
        }

        public void AddBatch(string sfSessionId, string sfJobId, byte[] fileBytes)
        {
            string reqURL = "https://cs12-api.salesforce.com/services/async/23.0/job/" + sfJobId + "/batch";
            XmlDocument respDoc = Post(fileBytes, reqURL, sfSessionId);
        }

        public XmlDocument Post(byte[] bytes, string reqURL, string sfSessionId)
        {
            WebRequest req = WebRequest.Create(reqURL);
            req.Method = "POST";
            req.ContentLength = bytes.Length;
            req.ContentType = "application/xml; charset=UTF-8"; // should be text/csv; when passing a CSV file
            req.Headers.Add("X-SFDC-Session: " + sfSessionId);

            System.IO.Stream strm = req.GetRequestStream();
            strm.Write(bytes, 0, bytes.Length);
            strm.Close();

            WebResponse resp = req.GetResponse();
            System.IO.Stream respStrm = resp.GetResponseStream();

            XmlDocument respDoc = new XmlDocument();
            respDoc.Load(respStrm);

            return respDoc;
        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            string SessionId = SalesforceLogin(this.TextBox1.Text, this.TextBox2.Text);
            string JobId = CreateJob(SessionId, "insert", "Contact");

            if (JobId.Length > 0)
            {
                AddBatch(SessionId, JobId, this.FileUpload1.FileBytes);
            }
        }
    }
}

Файл, который я публикую, совпадает с примером в документации.

FirstName,LastName,Department,Birthdate,Description
Tom,Jones,Marketing,1940-06-07Z,"Self-described as ""the top"" branding guru on the West Coast"
Ian,Dury,R&D,,"World-renowned expert in fuzzy logic design. 
Influential in technology purchases."

У меня вопрос , почему я получуОшибка синтаксического анализа XML от Salesforce в строке № 1, столбец 1 ?

Вот что я получаю:

XML Parsing Error: syntax error
Location: https://####.salesforce.com/services/async/23.0/job/###/batch/###/request
Line Number 1, Column 1:

FirstName,LastName,Department,Birthdate,Description
^

Любая помощь будет принята с благодарностью.Спасибо!

Ответы [ 2 ]

4 голосов
/ 31 января 2012

Прежде всего, никогда не создавайте xml со строковыми манипуляциями. Используйте синтаксический анализатор XML, например XmlDocument или XDocument.

Декларация Xml должна быть в отдельной строке <?xml version=\"1.0\" encoding=\"UTF-8\"?>. вы забыли \r\n

В-третьих, вы должны установить text/csv в качестве типа контента при отправке csv

2 голосов
/ 31 января 2012

В примере используется curl для отправки csv. Вы отправляете csv сервису, ожидающему xml. Найдите пример с данными XML или попробуйте вызывать с теми же параметрами, которые используются для curl.

...