I am trying to use SAP Business One Service Layer batch in order to achieve REST transactions. For a start, before dealing with actual data modification requests, I want to create a simple post to get two Business Partners in the same request. I tried writing a c# application, but I always get the same error:
{ "error" : { "code" : 242, "message" : { "lang" : "en-us", "value" : "Incomplete batch request body." } }
This is the code I am using:
public IRestResponse TestMultipart()
{
var client = new RestClient(new Uri(SERVICE_ROOT_URL));
client.CookieContainer = CookieCnt;
var request = new RestRequest("$batch", Method.POST)
{
AlwaysMultipartFormData = true
};
request.AddHeader("Content-Type", "multipart/mixed;boundary=batch_test1");
request.AddBody(@"--batch_test1
Content-Type: application/http
Content-Transfer-Encoding:binary
GET /b1s/v1/Invoices(1)
--batch_batch_test1
Content-Type: application/http
Content-Transfer-Encoding:binary
GET /b1s/v1/Invoices(2)
--batch_test1--");
return client.Execute(request);
}
(The authentication code, not included here, calls the Login API and initializes the CookieContainer. it works well: I am able to get responses for single (not multipart) requests using the standard GET method.)
I am unable to find a sample of multipart requests using the RestSharp library on the web. Can anybody help?
Thanks.
Ok, it turned out I got the whole thing wrong. I decided to use the HttpClient.Net native API, which allows very flexible creation of Multipart REST requests. Since I could not find decent documentation on how to create multipart/mixed content and putting all the pieces together required a bit of head scratching, I publish the code here, in case anyone finds it useful. This is the request handler, which resides in a SessioneSL class where the constructor opens the Service Layer session and stores the cookies into a CookieContainer instance which is a property of the class (this is still done in RestSharp and for this reason I wont publish it. I will convert it to a HttpClient version soon, ask if you need it).
public Task<string> TestMultipartHC()
{
using (var handler = new HttpClientHandler()
{
CookieContainer = CookieCnt,
Proxy = new WebProxy("127.0.0.1", 8888), // this is for catching the POST in Fiddler
})
{
HttpClient client = new HttpClient(handler)
{
BaseAddress = new Uri(SERVICE_ROOT_URL),
};
var myBoundary = "--batch_test1";
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, "$batch");
request.Headers.Date = DateTime.UtcNow;
request.Headers.Add("Accept", "application/json; charset=utf-8");
MultipartContent mpContent = new MultipartContent("mixed", myBoundary);
var sc = new StringContent("GET /b1s/v1/Invoices(1)");
sc.Headers.ContentType = new MediaTypeHeaderValue("application/http");
sc.Headers.Add("Content-Transfer-Encoding", "binary");
mpContent.Add(sc);
sc = new StringContent("GET /b1s/v1/Invoices(2)");
sc.Headers.ContentType = new MediaTypeHeaderValue("application/http");
sc.Headers.Add("Content-Transfer-Encoding", "binary");
mpContent.Add(sc);
request.Content = mpContent;
var response = client.SendAsync(request).Result;
return response.Content.ReadAsStringAsync();
}
}
To call this method, you will need a code such as this:
SessioneSL sessione = new SessioneSL();
Task<string> tk = sessione.TestMultipartHC();
tk.Wait();
Response.Write(tk.Result);
UPDATE 2020/05/06: The sample above didn't actually return the two objects, just the first one, I don't know why. Anyway, the transaction functionality only happens within a "Changeset" nested inside one multipart segment. Changesets only allow POST, PUT, DELETE, PATCH verbs, not get. The SAP documentation is terrible, so I still have to make trials.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.