Skip to Content

In this blog I’ll like to show you how to consume SAP Business One Service Layer oData sevices from a .NET application via WCF.

SAP Business One Service Layer is a new generation of extension API for consuming SAP Business One data and services. It builds on core protocols such as HTTP and OData, and provides a uniform way to expose full-featured business objects on top of a highly scalable and high-availability Web server. Currently, Service Layer supports OData version3, version 4, and a few selected OData client libraries, for example, WCF for .Net developers; data.js for JavaScript developers.

After installing SAP Business One Service Layer in your server (installed as part of the SAP Business One server components in the HANA Linux server) all documentation is available at the following link:

https://your_hana_server:50000 (your_hana_server is the name or IP of your HANA server)

Please also check the different documents and samples available in the main SAP Business One, version for SAP HANA Extensibility topics (http://scn.sap.com/docs/DOC-60454).

Development Environment

  1. Odata protocol version 3 is the highest version supported by WCF.
  2. You can choose to work with VS 2010, 2012 or 2013 for your daily work.
  3. As precondition, you need to get “WCF Data Services 5.6.0 Tools” installed in advance. You can get the installer from:
    http://www.microsoft.com/en-us/download/confirmation.aspx?id=39373.
  4. Next section explains  how to consume Odata Services via WCF.
  5. You can use Json.Net [NewtonSoft.Json.Net.dll] library for object serialization.
  6. Service Layer server needs to be configured with the following properties in the file b1s.conf (located in the Service Layer installation folder ServiceLayer/conf):
    1. “MetadataWithoutSession”: true
    2. “WCFCompatible”:true

After changing the configuration file you need to restart Service Layer by running the following command in /etc/init.d folder:
./b1s restart

How to consume Service Layer odata service via WCF

 Add the metadata as service or file directly by selecting “Add Service Reference” into your C#/.NET based Microsoft Visual Studio project, the metadata will be validated automatically.
Note: In order to be able to get the metadata you need first to open a session wiht Service Layer, for example via PostMan or any other tool.

SL_AddServiceReference.png

 

Microsoft Visua Studio IDE will use a tool named “SvcUtil.exe” to validate the metadata XML and generate proxy class for your usage automatically if validate passed. You can find all classes in “ObjectBrowser”.

 

SL_ObjectBrowser.png

 

With the automatically generated proxy classes, you can program the required business logic of your application.

 

Sample Code

You can download a .NET sample code connecting to SAP Business One version for SAP HANA Service Layer and doing some operations like:

– Login/Logout

– Retreive the list of Business Partners and Items

– Add a Sales Order Document

– Update a Sales Order Document

– Get a specific Sales Order Document

– Close a Sales Order Document

– Get information via query filters to reduce the amount of data to be retrieved (for example not all fields but only CardCode, CardName fields required but the UI) to improve performances

– Send several queries via Batch in only one request

– Use pagination to retrieve all Orders page by page (user will not be able to see all pages at once and performances will be better if you retrieve page by page).

With this sample you will see how easy is to consume Service Layer Entities (what we are using to call objects in COM interface) and Actions (somehow equivalent to the DI API Services) by getting directly your hands in real .NET C# code.

Please use our standard SDK forum for questions/remarks on the SAP Business One version for SAP HANA Service Layer.

DOWNLOAD IT FROM HERE

Enjoy it!

To report this post you need to login first.

20 Comments

You must be Logged on to comment or reply to a post.

  1. Rahul Jain

    Hello Sir,

    I am getting the below error, when I am adding the service reference in my c# windows application. Please look @ this & let me know the appropriate solution.

     

    (1) 
    1. Former Member

      I am having the same problem. How do i add a reference to an OData service. Here are the first few lines of $metadata. Is there a version problem that Visual Studio does not understand.

      Please help SAP!

       

      <edmx:DataServices m:DataServiceVersion=”2.0>
      <Schema xmlns=”http://schemas.microsoft.com/ado/2008/09/edm Namespace=”HCM_LEAVE_REQ_CREATE_SRV xml:lang=”en sap:schema-version=”1>
      <EntityType Name=”AbsenceType sap:content-version=”1>
      (0) 
  2. Maria Trinidad MARTINEZ GEA Post author

    Hi Tanakorn,

    Your question is not directly related to that blog but in general to B1 behavior on DocEntry numbering.

    Can you please post this question on the community forum? I’ll remove it from here in the coming days.

    Regards,
    Trinidad.

    (0) 
  3. R. Pol

    Hi Maria,

    I have downloaded your application and a system administrator has done the settings for point 6. under Development Environment.

    When i start the application, i can Login, Load Initial Data, Add New Order and Get Order. So i assume all my settings are correct!?

    However, when i do Get Order Pages, i get the following error (twice):
    A null value was found for the property named ‘SystemSerialNumber’, which has the expected type ‘Edm.Int32[Nullable=False]’. The expected type ‘Edm.Int32[Nullable=False]’ does not allow null values.

    When i check REFDI.chm to see what field corresponds with ‘SystemSerialNumber’, it is ‘SysSerial’. When i check the database which tables contain this field, i find 3 tables (‘SRI1_LINK’, ‘OSRI’ and ‘SRI1’). When i check these tables, there are no entries with ‘SysSerial’ is null!?

    I am using SAP B1 9.2 PL 8 and Visual Studio 2015.

    Question 1: Any idea what might be wrong?

    Also, i notice that you are using 2 methods to get data.

    1) An actual service call to login

    Uri login = new Uri(“https://<server ip>:50000/b1s/v1/” + “Login”);
    BodyOperationParameter[] body = new BodyOperationParameter[3];
    body[0] = new BodyOperationParameter(“UserName”, cred.UserName);
    body[1] = new BodyOperationParameter(“Password”, cred.Password);
    body[2] = new BodyOperationParameter(“CompanyDB”, cred.CompanyDB);
    session = (B1Session)currentServiceContainer.Execute<B1Session>(login, “POST”, true, body).SingleOrDefault();

    2) Through the Service Layer object

    BusinessPartner bp = currentServiceContainer.BusinessPartners.Where(cursor => cursor.CardCode == cardCode).SingleOrDefault();

    Question 2 intro:
    I want to get Company Details.

    When i check the Service Layer Object (method 2), it does not contain a definition for AdminInfo. Therefor i need to use method 1.

    I want to get ADM1.Street and such, but from what i can tell i need to use /b1s/v1/CompanyService_GetAdminInfo and than extract the individual address field values from the ‘Address’ field…

    When i add the following code, i get an error:

    var admin = new Uri(“https://<server ip>:50000/b1s/v1/” + “CompanyService_GetAdminInfo”);
    var adminInfo = currentServiceContainer.Execute<AdminInfo>(admin, “POST”, true).SingleOrDefault();

    InnerException: {“The response payload is a not a valid response payload. Please make sure that the top level element is a valid Atom or JSON element or belongs to ‘http://schemas.microsoft.com/ado/2007/08/dataservices’ namespace.”}

    When i do the same call using Postman, i do get a valid response…

    Then i think to myself, ok, lets try with a BusinessPartner:

    var bp = new Uri(“https://<server ip>:50000/b1s/v1/” + “BusinessPartners”);
    var bpInfo = currentServiceContainer.Execute<BusinessPartner>(bp, “GET”, false);

    This works fine (this makes me think that all my settings are indeed correct)…

    Question 2: How do i get AdminInfo?

    With kind regards,

    Ruben Pol

    (0) 
  4. Maria Trinidad MARTINEZ GEA Post author

    Hi Ruben,

    Here you have a sample for getting the CompanyService_GetCompanyInfo.

    Can you please check if this code works for you and afterwards adapt it for AdminInfo instead of CompanyInfo?

    If not working please post a question outside this blog comments, it is not easy to get it managed here, just post the link here.

    public string CompanyService_GetCompanyInfo()
    {
    CompanyInfo cmpInfo = null; // ComplexType!
    try
    {
    //Format the URI
    string strFormat = “{0}/{1}”;
    string strURL = strCurrentServerURL;
    if (strCurrentServerURL.EndsWith(“/”))
    strURL = strURL.Remove(strURL.Length – 1); //remove last /, to avoid duplication

    string strRequstCmd = string.Empty;

    //HTTP Request Command Type
    string strCommandType = “POST”;

    string strAction = “CompanyService_GetCompanyInfo”;

    strRequstCmd = string.Format(strFormat, strURL, strAction);
    Uri cmdQuery = new Uri(strRequstCmd);

    //Enacpsulate the parameters if necessary
    BodyOperationParameter[] body = null;
    cmpInfo = (CompanyInfo)currentServiceContainer.Execute<CompanyInfo>(cmdQuery, strCommandType, true, body).SingleOrDefault();

    return cmpInfo.CompanyName;
    }
    catch (Exception ex)
    {
    throw ex;
    }
    }

    Hope it helps

    Trinidad.

    (0) 
  5. Former Member

    Hello ,

    thank you so much for the interesting tuto

    i want to know if I can use service layer inside my SAP B1 addon instead of DI API

    best regards

    Radhia HENOUZ

    (0) 
    1. Miklós Németh

      Yes, absolutely. You can even apply Single-Sign-On with the help of the new UI API function in the Company COM interface, GetServiceLayerConnectionContext. You will receive the cookie string for B1SESSION. The UI API performs the login for you this way.

       

      (1) 
  6. R. Pol

    Hi Trinidad,

    When using your code I had an issue when i wanted to create an Invoice based on a Delivery. With the help from SAP support i found out that i had to change 1 of the functions from your sample program. As to keep your page readable, I made a blog post with the solution provided by SAP support (https://blogs.sap.com/?p=642503)…

    With kind regards,

    Ruben

    (2) 
  7. Former Member

    Hi,

    I have facing problem.

    when updating Sales order using Service Layer.

    Error is -5002 :- Internal error (-5002) occurred.

    Code :-

    SalesOrder = currentServiceContainer.Orders.Where(cursor => cursor.DocEntry == model.DocEntry).SingleOrDefault();
    SalesOrder.Comments = “Change it yo”;
    currentServiceContainer.UpdateObject(SalesOrder);
    currentServiceContainer.SaveChanges(SaveChangesOptions.PatchOnUpdate);

     

    (0) 
  8. Former Member

    I appreciate your efforts but when I restarting service layer after configuration, the following error occured. i can not use http://server:50000/b1s/v1/login 

    (0) 
  9. Raul Zapata Pasos

    Hello Trinidad,

     

    I’m trying to Add the Service reference to my visual studio project, but then credentials are requested and I’m not sure which credentials I must use; It’s important to mention previously I have logged in using postman

     

    Do you know how can I solve this issue?

    Thanks

    (0) 
      1. Jose Amaya

        Hello guys

        I’m facing the same issue here when trying to add the web reference for service layer to the VS Project, tried it as a web reference and as a service reference and failed both because of this.

        @raul.zapatapasos @umity did you guys could resolve this problem? have any pointers?

        Dear @mariatrinidad.martinezgea could you point us somewhat in a better direction?

         

        Best regards

         

        (0) 
        1. Ümit Yavuz

          Hello Jose,

          I solved the problem. I added  MetadataWithoutSession : true   and WCFCompatible :true  b1s.conf file. it’s okey.

           

          Best Regards.

          (0) 

Leave a Reply