简体   繁体   中英

Sending Batch REST requests to SAP Business One Service Layer using RestSharp

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM