cancel
Showing results for 
Search instead for 
Did you mean: 

B1 SQL Servicelayer connection using UI API

09-03-2020 2:07 PM
qscvisag Explorer
2838 views 6 comments
0 Likes
SAP Managed Tags
Subscribe

In Short: Company.GetServiceLayerConnectionContext(BaseUri); throws Exception "General Failure"

SAP B1 10.00.120 PL02 for SQL

Service Layer is installed and can be reached via Postman

My Intention: Reading the Businesspartner Object from Servicelayer in a Desktop (C#) AddOnContext

I was following the Instructions in this article: https://blogs.sap.com/2016/07/01/sap-business-one-service-layer-sso-with-ui-api/

BaseUri is set to "https://qsc-mobile:50000/b1s/v1/"

Stacktrace:

Exception thrown: 'System.Runtime.InteropServices.COMException' in VisECommerceAddOn.dll
General Failure
   bei SAPbouiCOM.CompanyClass.GetServiceLayerConnectionContext(String inConnParam)
   bei VisECommerceAddOn.Logic.ServiceLayer.PrepareRequest(String method, String path, Object content) in D:\dev\VIS2\SAPAddOns\4.0\VisECommerceAddOn\VisECommerceAddOn\Logic\ServiceLayer.cs:Zeile 60.
   bei VisECommerceAddOn.Logic.ServiceLayer.GetBusinessPartner(String cardCode) in D:\dev\VIS2\SAPAddOns\4.0\VisECommerceAddOn\VisECommerceAddOn\Logic\ServiceLayer.cs:Zeile 32.
   bei VisECommerceAddOn.Logic.BPUpload.UploadShopBps(List`1 contactsToUpload, ShopModel shop) in D:\dev\VIS2\SAPAddOns\4.0\VisECommerceAddOn\VisECommerceAddOn\Logic\BPUpload.cs:Zeile 59.
   bei VisECommerceAddOn.Frontend.BPManagement.BPManagementForm.UploadBtn_Click(Object sender, EventArgs e) in D:\dev\VIS2\SAPAddOns\4.0\VisECommerceAddOn\VisECommerceAddOn\Frontend\BPManagement\BPManagementForm.cs:Zeile 497.
public class ServiceLayer
    {
        private Company Company;
        private string BaseUri;
        public ServiceLayer(string baseUri)
        {
            Company = SwissAddonFramework.B1Connector.GetB1Connector().Application.Company;
            BaseUri = baseUri;
        }

        public BusinessPartner GetBusinessPartner(string cardCode)
        {
            var path = $"BusinessPartners('{cardCode}')";
            var req = PrepareRequest("GET", path);
            var resp = req.GetResponse() as HttpWebResponse;
            var result = ReadResponse<BusinessPartner>(resp);
            return result;
        }

        private T ReadResponse<T>(HttpWebResponse response) where T : class
        {
            T result = null;
            using (var stream = response.GetResponseStream())
            {
                using (var streamReader = new StreamReader(stream))
                {
                    var content = streamReader.ReadToEnd();
                    if (response.ContentType != JsonContentType)
                    {
                        throw new WrongContentTypeException();
                    }
                    result = JsonConvert.DeserializeObject<T>(content);
                }
            }
            response.Close();
            return result;
        }
        private const string JsonContentType = "application/json";
        private HttpWebRequest PrepareRequest(string method, string path, object content = null)
        {
            var cookies = Company.GetServiceLayerConnectionContext(BaseUri);
            path = path.StartsWith("/") ? path.Substring(1) : path;
            var requestUri = BaseUri + path;
            var request = WebRequest.Create(requestUri) as HttpWebRequest;
            request.Method = method;
            if (content != null)
            {
                request.ContentType = JsonContentType;
                using var stream = request.GetRequestStream();
                using var streamWriter = new StreamWriter(stream);
                var json = JsonConvert.SerializeObject(content);
                streamWriter.Write(json);
            }
            request.CookieContainer = new CookieContainer();
            string[] cookieItems = cookies.Split(';');
            foreach (var cookieItem in cookieItems)
            {
                string[] parts = cookieItem.Split('=');
                if (parts.Length == 2)
                {
                    request.CookieContainer.Add(request.RequestUri, new Cookie(parts[0].Trim(), parts[1].Trim()));
                }
            }
            return request;
        }
    }

Is there a Logfile I could consult for more information about this bug/ behaviour?

Best Regards

Quentin Schär

0 Likes

Accepted Solutions (0)

Answers (1)

Answers (1)

PierreBrothier
Contributor
0 Likes

Hi,

when you use GetServiceLayerConnectionContext, be sure there's no / at the end of your base url.

    if (l_B1ServiceLayerURL.LastIndexOf("/") == (l_B1ServiceLayerURL.Length - 1))
            {
                l_B1ServiceLayerURL = l_B1ServiceLayerURL.Substring(0, l_B1ServiceLayerURL.Length - 1);
            }


            //récupération de la connection               
            l_Result = Application.SBO_Application.Company.GetServiceLayerConnectionContext(l_B1ServiceLayerURL);


qscvisag
Explorer
0 Likes

Thanks for the quick response. Unfortunately I've already tried that with the same result.

Also v1 or v2 does not make a difference.

PierreBrothier
Contributor
0 Likes

the problem seems to be on diapi side, so perhaps you could change log level in the B1 client through "Help" -> "Support Desk" -> "Logger Settings"

Detail log would be helpful !

qscvisag
Explorer
0 Likes

Thank you for the hint.

The SAP Client Log points to an error with Workflows/ Login clientb1logger20200903-145237pid33328logcsv.txt

The Access logfiles from ServiceLayer show something like this:

[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 169915 "POST /b1s/v1/Login HTTP/1.1" 401 108 ssl=TLSv1.2 t=0s pid=10244 sid=- n=- +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 165925 "POST /b1s/v1/Login HTTP/1.1" 401 108 ssl=TLSv1.2 t=0s pid=10244 sid=- n=- +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 997 "GET //b1s/v1/Logout HTTP/1.1" 204 - ssl=TLSv1.2 t=0s pid=10244 sid=- n=.node2 +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 186870 "POST /b1s/v1/Login HTTP/1.1" 401 108 ssl=TLSv1.2 t=0s pid=10244 sid=- n=- +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 998 "GET //b1s/v1/Logout HTTP/1.1" 204 - ssl=TLSv1.2 t=0s pid=10244 sid=- n=.node3 +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 987 "GET //b1s/v1/Logout HTTP/1.1" 204 - ssl=TLSv1.2 t=0s pid=10244 sid=- n=.node1 +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 170929 "POST /b1s/v1/Login HTTP/1.1" 401 108 ssl=TLSv1.2 t=0s pid=10244 sid=- n=- +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 997 "GET //b1s/v1/Logout HTTP/1.1" 204 - ssl=TLSv1.2 t=0s pid=10244 sid=- n=.node5 +
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 245728 "POST /b1s/v1/Login HTTP/1.1" 400 117 ssl=TLSv1.2 t=0s pid=10244 sid=- n=- -
[03/Sep/2020:15:18:51 +0200] fe80::8d5:cb3:589:556e 1031 "GET //b1s/v1/Logout HTTP/1.1" 204 - ssl=TLSv1.2 t=0s pid=10244 sid=- n=.node4 + 

I'm guessing 401 and 204 are the http status codes (401- Unauthorized, 204- NoContent)

In both cases (B1 and Postman) I'm using the manager user with B1 prof license on a Demo db.

Is there another logfile that would be more helpful?

PierreBrothier
Contributor
0 Likes

I've just test the code on SAP B1 10.00.120 PL02 for HANA, and it is working.

I don't have latest SQL version environment. Since Service Layer is quite new for SQL, perhaps it's specific to this version.

I can only reproduce general failure when adding / at the end of the base url.

Simon_nAG
Participant
0 Likes

Same issue here on FP2305. For the "Gernal failure" there is a note: https://me.sap.com/notes/3261423/E

Does anyone have this work an FP2305 or higher?