You need to sign in to do that
Don't have an account?

Salesforce Bulk Api in C#:returning Error" The remote server returned an error: (400) Bad Request"
Below is the code in C# for Bulk Api.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.VisualBasic; using System.Collections; using System.Data; using System.Diagnostics; using System.Xml; using System.IO; using System.Net; namespace ConsoleApplication7 { class Program { private static SForceService.SforceService bindingService { get; set; } private static void QueryUsingBulkAPI() { string jobId = string.Empty; string resultId = string.Empty; string batchId = string.Empty; //new code Console.Write("Enter user name: "); string userName = Console.ReadLine(); Console.Write("Enter password: "); string password = Console.ReadLine(); ////Provide feed back while we create the web service binding Console.WriteLine("Creating the binding to the web service..."); // Create the binding to the sforce servics bindingService = new SForceService.SforceService(); // Set the time out value bindingService.Timeout = 60000; ////Attempt the login giving the user feedback Console.WriteLine("LOGGING IN NOW...."); try { SForceService.LoginResult loginRes = bindingService.login(userName, password); Console.WriteLine(loginRes); Console.WriteLine( "The session id is: " + loginRes.sessionId); Console.WriteLine("The new server url is: " + loginRes.serverUrl); //Change the binding to the new endpoint bindingService.Url = loginRes.serverUrl; //Create a new session header object and set the session id to that returned by the login bindingService.SessionHeaderValue = new SForceService.SessionHeader(); bindingService.SessionHeaderValue.sessionId = loginRes.sessionId; Debug.WriteLine(loginRes.sessionId); CreateJob(loginRes.sessionId, "query", "Case", ref jobId); //e.g for inserting contact //Dim jobId As String = CreateJob(loginRes.sessionId, "insert", "Contact") byte[] inputFileData = null; if ((jobId.Length > 0)) { //data loading using a sampe file // Open a file that is to be loaded into a byte array System.IO.FileInfo oFile = null; //oFile = New System.IO.FileInfo("data.csv") oFile = new System.IO.FileInfo("request.txt"); System.IO.FileStream oFileStream = oFile.OpenRead(); long lBytes = oFileStream.Length; int a = (int)lBytes; //modified after conversion if ((lBytes > 0)) { byte[] fileData = new byte[lBytes]; // Read the file into a byte array oFileStream.Read(fileData, 0, a); //modified after conversion oFileStream.Close(); //Get the file where the Query is present inputFileData = fileData; } //Adds the batch to SalesForce AddBatch(loginRes.sessionId, inputFileData, jobId, batchId, resultId); //Check Status and Get BatchId and ResultsId GetStatusAndRetrieveBatchIdAndResultsId(loginRes.sessionId, jobId, ref batchId, ref resultId); //Get Results Id RetrieveResults(loginRes.sessionId, jobId, batchId, resultId); } } catch (System.Web.Services.Protocols.SoapException e) { //// This is likley to be caused by bad username or password Console.Write(e.Message + ", please try again." + "Hit return to continue..."); Console.ReadLine(); } catch (Exception ex) { //// This is something else, probably comminication Console.Write(ex.Message + ", please try again." + "Hit return to continue..."); Console.ReadLine(); } //new code end //Used to create the Job in SalesForce-- //the Job can be query, insert, delete etc...This is the operation parameter //eg for querying Case } /// <summary> /// Creates a job in Salesforce /// </summary> /// <param name="sfSessionId"></param> /// <param name="sfOperation"></param> /// <param name="sfObjectName"></param> /// <param name="jobId"></param> /// <remarks></remarks> public static void CreateJob(string sfSessionId, string sfOperation, string sfObjectName, ref string jobId) { string str = ""; string reqURL = ""; byte[] bytes = null; XmlDocument reqDoc = null; XmlDocument responseXmlDocument = new XmlDocument(); str = "" + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + "<jobInfo xmlns=\"http://www.force.com/2009/06/asyncapi/dataload\">" + " <operation></operation>" + " <object></object>" + " <contentType>CSV</contentType>" + "</jobInfo>"; //Eg for XML content type //" <contentType>XML</contentType>" & reqURL = "https://na1.salesforce.com/services/async/28.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); //bytes = System.Text.Encoding.UTF8.GetBytes(reqDoc.InnerXml) using (Stream responseStream = Post(bytes, reqURL, sfSessionId, "POST", "text/csv; charset=UTF-8")) { responseXmlDocument.Load(responseStream); //Get jobId jobId = ((((responseXmlDocument) != null)) ? responseXmlDocument.GetElementsByTagName("id").Item(0).InnerText : ""); } } /// <summary> /// Adds the Batch to SalesForce /// </summary> /// <param name="sfSessionId"></param> /// <param name="fileBytes"></param> /// <param name="sfJobId"></param> /// <param name="sfBatchId"></param> /// <param name="sfResultId"></param> /// <remarks></remarks> public static void AddBatch(string sfSessionId, byte[] fileBytes, string sfJobId, string sfBatchId = null, string sfResultId = null) { string requestURI = ("https://login.salesforce.com/services/async/23.0/job/" + (sfJobId + "/batch")); Post(fileBytes, requestURI, sfSessionId, "POST", "text/csv; charset=UTF-8"); } /// <summary> /// Once the batch is added get the BatchId and then /// once the processing is done , get the Results ID /// </summary> /// <param name="sfSessionId"></param> /// <param name="sfJobId"></param> /// <param name="batchId"></param> /// <param name="resultId"></param> /// <remarks></remarks> public static void GetStatusAndRetrieveBatchIdAndResultsId(string sfSessionId, string sfJobId, ref string batchId, ref string resultId) { XmlDocument responseXmlDocument = new XmlDocument(); string reqURL = ("https://na1.salesforce.com/services/async/23.0/job/" + sfJobId + "/batch"); //Get BatchId using (System.IO.Stream responseStream = Post(null, reqURL, sfSessionId, "GET", "text/csv; charset=UTF-8")) { responseXmlDocument.Load(responseStream); batchId = ((((responseStream) != null)) ? responseXmlDocument.GetElementsByTagName("id").Item(0).InnerText : ""); } //Get ResultId reqURL = ("https://na1.salesforce.com/services/async/23.0/job/" + (sfJobId + "/batch/" + batchId + "/result")); using (System.IO.Stream responseStream = Post(null, reqURL, sfSessionId, "GET", "text/csv; charset=UTF-8")) { responseXmlDocument.Load(responseStream); resultId = ((((responseStream) != null)) ? responseXmlDocument.GetElementsByTagName("result").Item(0).InnerText : ""); } } /// <summary> /// Post the rest call with batch id and results id to get the output /// </summary> /// <param name="sfSessionId"></param> /// <param name="sfJobId"></param> /// <param name="sfBatchId"></param> /// <param name="sfResultId"></param> /// <remarks></remarks> public static void RetrieveResults(string sfSessionId, string sfJobId, string sfBatchId, string sfResultId) { string reqURL = ("https://na1.salesforce.com/services/async/23.0/job/" + (sfJobId + "/batch/" + sfBatchId + "/result/" + sfResultId)); string localFile = "output.csv"; //Create the output file using (System.IO.Stream responseStream = Post(null, reqURL, sfSessionId, "GET", "text/csv; charset=UTF-8")) { using (System.IO.FileStream fsOutputFile = new System.IO.FileStream(localFile, FileMode.Create, FileAccess.Write)) { byte[] buffer = new byte[2048]; int read = 0; do { read = responseStream.Read(buffer, 0, buffer.Length); fsOutputFile.Write(buffer, 0, read); } while (!(read == 0)); responseStream.Close(); fsOutputFile.Flush(); fsOutputFile.Close(); } responseStream.Close(); } } /// <summary> /// Function to POST the HTTP rest request /// </summary> /// <param name="bytes"></param> /// <param name="reqURL"></param> /// <param name="sfSessionId"></param> /// <param name="method"></param> /// <param name="contentType"></param> /// <returns></returns> /// <remarks></remarks> public static Stream Post(byte[] bytes, string reqURL, string sfSessionId, string method, string contentType) { //Create the request object WebRequest requestHttp = WebRequest.Create(reqURL); //Assign the type of request POST,GET.. requestHttp.Method = method; //Assign Content Type requestHttp.ContentType = contentType; //"text/csv; charset=UTF-8" or "application/xml; charset=UTF-8" //Assign the session id to the header requestHttp.Headers.Add(("X-SFDC-Session: " + sfSessionId)); //Assign byte length if ((bytes != null)) { requestHttp.ContentLength = bytes.Length; System.IO.Stream strmHttpContent = requestHttp.GetRequestStream(); strmHttpContent.Write(bytes, 0, bytes.Length); strmHttpContent.Close(); } //Get the response object String responseFromServer; try { //Call the service and get the response HttpWebResponse response = (HttpWebResponse)requestHttp.GetResponse(); if (HttpStatusCode.OK == response.StatusCode) { Stream dataStream = response.GetResponseStream(); StreamReader reader = new StreamReader(dataStream); responseFromServer = reader.ReadToEnd(); response.Close(); } } catch (WebException e) { using (WebResponse response = e.Response) { HttpWebResponse httpResponse = (HttpWebResponse)response; responseFromServer = string.Format("Error code: {0} ", httpResponse.StatusCode); using (Stream data = response.GetResponseStream()) { responseFromServer += new StreamReader(data).ReadToEnd(); // return responseFromServer; Console.WriteLine("reponse from server" + responseFromServer); } } } //Return response Stream WebResponse responseHttpRequest = requestHttp.GetResponse(); return responseHttpRequest.GetResponseStream(); } static void Main(string[] args) { QueryUsingBulkAPI(); } } }
Its returning the following output with Error:
Enter user name: sfuserid
Enter password: paswd+token
Creating the binding to the web service...
LOGGING IN NOW....
ConsoleApplication7.SForceService.LoginResult
The session id is: 00D90000000k6uO!ARoAQH02gPYFrZmt2RDkBNSXKZrEZLQv9jmAh2lXPaqAp
AsEu0zUbpTUC5mDn0FIHk2cCeYMuDjEIJeXnVfn.ccD1jW31IM3
The new server url is: https://ap1.salesforce.com/services/Soap/u/28.0/00D900000
00k6uO
reponse from serverError code: BadRequest <?xml version="1.0" encoding="UTF-8"?
><error
xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<exceptionCode>InvalidSessionId</exceptionCode>
<exceptionMessage>Invalid session id</exceptionMessage>
</error>
The remote server returned an error: (400) Bad Request., please try again.Hit
return to continue...
Please help me resolve the Error.The bad request is due to invalid session id,but when i am printing the session id it has a valid value.Please tell me where the prblm is in the above code.
Thanks in advance.
I got the solution to this.
The Error was due to the Request URL
Which when i changed to the below it worked fine
https://ap1-api.salesforce.com/services/async/28.0/job/
Syntax of URL is:"https://instancename-api.salesforce.com/services/async/apiversion/job/"
where instancename --> server name of instance
apiversion --> can be found out from partner wsdl in develop-->API
Thanks.
Urvashi.
All Answers
I got the solution to this.
The Error was due to the Request URL
Which when i changed to the below it worked fine
https://ap1-api.salesforce.com/services/async/28.0/job/
Syntax of URL is:"https://instancename-api.salesforce.com/services/async/apiversion/job/"
where instancename --> server name of instance
apiversion --> can be found out from partner wsdl in develop-->API
Thanks.
Urvashi.
Hi Urvashi,
Thanks for posting the code.
Question how to update master & detail in one shot.
And currently we have CSHistory as Header & CSHistory Items as Details. 2 Objects in SFDC.
Can you able to create header and details in single shot? through bulk api. if so can you please show me a single example
Thank you
Regards,
Lance
I am trying to get some records from a object but in the code above i am not sure where the query really is. I am also not sure what 'request.txt' is. Kindly help me out.
Thanks,
Manognya