Search code examples
c#magentosoapwsdlmagento-soap-api

How do i Configure the token based authentication of Magento 2.0 SOAP API object in .Net application


i am trying to consume the newly introduced Magento 2.0 SOAP API in .Net application. but as per the newly structured endpoints wsdl changes,function calling execution are little bit different from the earlier version..

Is Anyone has hands on in consumption and calling of web API Soap object function of Magento 2.0 in .Net application??

if yes can you provide some snippet code of the same.

Thanks in advance!


Solution

  • I finally got the Magento 2 SOAP API and .NET talking to each other. Here is the step-by-step that worked for me:

    In the Magento 2 Backend

    System > Integrations > Add New Integration

    Only fill out name and email here since we just want to post back to our own store and let Magento save the tokens and keys for you. Don't forget to set your permissions for the integration on the separate tab.

    NOTE: If you're using a VM make sure your /etc/hosts file has an entry for itself since the web server will be posting back to itself.

    You should have an access token displayed in the response. Make a note of it for later.

    In Visual Studio 2013

    In your project Solution Explorer, right click References and choose Add Service Reference The address will be something like:

    http://MyMagentoStore.com/soap/default?wsdl=1&services=catalogProductAttributeGroupRepositoryV1,catalogProductAttributeManagementV1

    Where services= is followed by a comma-delimited list of the services you will be consuming.

    To see all available services, visit the following url in your store:

    http://MyMagentoStore.com/soap/default?wsdl_list=1

    I wouldn't recommend choosing all of them since it will make the SOAP call URLs extremely long. I ended up grouping the services into sections like catalogProduct, customer, etc and creating indivual services references for each set.

    Construct your URL and paste it into the Add Service Reference dialog and click Go.

    If you did choose to break the services apart like me, just give each service a good namespace. I went with Magento2Soap.Customer, Magento2Soap.CatalogProduct, etc. In any case, choose a namespace at the bottom of the dialog and click OK. This will generate the code to connect to Magento.

    Actually talking to Magento successfully

    Now the hardest part to figure out: Actually getting it to work.

    You have to use the WCF libraries to add the proper Authorization Header in your SOAP calls. Doing this was not obvious. Here is a snippet:

        var client = new customerCustomerRepositoryV1PortTypeClient();
        client.Endpoint.Binding = new BasicHttpBinding();
    
        HttpRequestMessageProperty hrmp = new HttpRequestMessageProperty();
        hrmp.Headers.Add("Authorization", "Bearer " + yourAccessToken);
    
        OperationContextScope contextScope = new OperationContextScope(client.InnerChannel);
        OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = hrmp;
    
        CustomerCustomerRepositoryV1GetByIdResponse response = client.customerCustomerRepositoryV1GetById(
            new CustomerCustomerRepositoryV1GetByIdRequest() { 
                customerId = 1 
            }
        );
        Console.WriteLine(response.result.firstname);
    

    Note that you will need to add a project reference to System.ServiceModel. You can do this by right-clicking References in your Solution Explorer and then Add Reference. It will be in the list of core libraries.

    I never found a great way to use polymorphism for each different type of call since the generated classes don't inherit from any common class or interface, and I wasn't going to go near the dynamic type. I ended up making a static class to simplify things:

    public static class MagentoSOAP {
    
        private static BasicHttpBinding GetBinding() {
            return new BasicHttpBinding();
        }
    
        private static void AddAuthorizationHeader(IClientChannel clientChannel) {
            HttpRequestMessageProperty hrmp = new HttpRequestMessageProperty();
            hrmp.Headers.Add("Authorization", "Bearer " + Constants.MAGENTO_SOAP_ACCESS_TOKEN);
    
            OperationContextScope contextScope = new OperationContextScope(clientChannel);
            OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = hrmp;
        }
    
        public static customerCustomerRepositoryV1PortTypeClient Customer {
            get {
                var client = new customerCustomerRepositoryV1PortTypeClient();
                client.Endpoint.Binding = GetBinding();
                AddAuthorizationHeader(client.InnerChannel);
                return client;
            }
        }
    
        public static catalogProductRepositoryV1PortTypeClient Product {
            get {
                var client = new catalogProductRepositoryV1PortTypeClient();
                client.Endpoint.Binding = GetBinding();
                AddAuthorizationHeader(client.InnerChannel);
                return client;
            }
        }
    }
    

    And in practice:

    var product = MagentoSOAP.Product.catalogProductRepositoryV1Get(new Magento2SOAP.CatalogProduct.CatalogProductRepositoryV1GetRequest() {
        sku = "My Product SKU"
    });
    int id = product.result.id;
    

    I hope this is helpful. I welcome any improvements or suggestions.