cancel
Showing results for 
Search instead for 
Did you mean: 

ICI WSDL using .Net WCF Service

Former Member
0 Kudos

Hello,

I am trying to develop a customer adapter which will integrating into the SAP CRM using the SAP ICI Interface. The adapter will be developed using .Net Framework 4.0 and using WCF framework to build the necessary services that SAP can call.

I have the SAP ICI WSDL files that I have processed using the svcutil.exe tool to generate the necessary server side intefaces for the customer adapter. The problem that I am having is when I call any method on the WCF server passing the necessary request object I get 'Cannot convert object of type 'xxx' to type 'xxx' error. This could be mainly due to serialization/deserialization or becuase there is a issue with the server code that I have generated using the svcutil tool.

Does anyone have implemented the ICI WSDL into a WCF service successfully or had similar issues.

Your help/input is highly appreciated.

Thanks,

Sanket Banawalikar

Accepted Solutions (0)

Answers (2)

Answers (2)

former_member645959
Discoverer
0 Kudos

Hello Sanket,

I had a prototype working some time ago.

At the time I used Visual Studio 2010 to generate the code from the WSDL files. I got those using a server I had access at the time.

Example for IciPhoneCall

http://[server_name]:83/soapdispatcher?WSDL=IciPhoneCallBean

The WSDL files didn't have the latest changes to the protocol, I don't know if SAP has updated these files in the meantime. So, I had to change some of the files after being generated.

After that I still wasn't able to invoke the subscribe and unsubscribe methods because, apparently, WCF was getting confused with the same operation names for "containers" (phone lines, emails and chats) and "users". I implemented two classes to workaround that issue:

public class DispatchByBodyElementOperationSelector : IDispatchOperationSelector

{

        List<String> dispatchOperations;

        public DispatchByBodyElementOperationSelector(List<string> dispatchOperations)

        {

            this.dispatchOperations = dispatchOperations;

        }

        #region IDispatchOperationSelector Members

        private Message CreateMessageCopy(Message message, XmlDictionaryReader body)

        {

            Message copy = Message.CreateMessage(message.Version,message.Headers.Action,body);

            copy.Headers.CopyHeadersFrom(message);

            //Remove the duplicated "Action" header...

            copy.Headers.RemoveAt(message.Headers.Count);

            copy.Properties.CopyProperties(message.Properties);

            return copy;

        }

        public string SelectOperation(ref System.ServiceModel.Channels.Message message)

        {

            XmlDictionaryReader bodyReader = message.GetReaderAtBodyContents();

            message = CreateMessageCopy(message, bodyReader);

            Console.WriteLine("Got name {0}", bodyReader.Name);

            string interfacePrefix = bodyReader.NamespaceURI.Split(':')[1];

            string opname = bodyReader.Name;

            if (opname.Contains(":"))

                opname = opname.Split(':')[1];

            if (dispatchOperations.Contains(opname))

            {

                return opname;

            }

            else

            {

                if (opname.ToLower() == "subscribe" || opname.ToLower() == "unsubscribe")

                {

                    if (interfacePrefix == "IciUserInterface")

                        return opname;

                    if (interfacePrefix == "IciContainerInterface")

                        return opname;

                }

                return null;

            }

        }

        #endregion

    }

and

    [AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface)]

    public sealed class DispatchByBodyBehaviorAttribute : Attribute, IContractBehavior

    {

        #region IContractBehavior Members

        public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)

        {

            // no binding parameters need to be set here

            return;

        }

 

        public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)

        {

            // this is a dispatch-side behavior which doesn't require

            // any action on the client

            return;

        }

 

        public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)

        {

            // We iterate over the operation descriptions in the contract and

            // record the QName of the request body child element and corresponding operation name

            // to the dictionary to be used for dispatch

 

            List<String> dispatchOperations = new List<string>();

             foreach( OperationDescription operationDescription in contractDescription.Operations )

            {

                 dispatchOperations.Add(operationDescription.Name);

            }

           

            // Lastly, we create and assign and instance of our operation selector that

            // gets the dispatch dictionary we've just created.

            dispatchRuntime.OperationSelector =

                new DispatchByBodyElementOperationSelector(dispatchOperations);

        }

        public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)

        {

            //

        }

        #endregion

    }

In the class implementing the service handling:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single, Namespace = "http://whatever/sapici"), DispatchByBodyBehavior]

public class ServiceHandler : <all the implemented interfaces>


Also, at the time there was a problem with the deserialization of responses to SAP ICI responses. After changing to "Qualified" instead of "Unqualified" all seems to work...

Sorry for the messy message!

Hope this helps,

jars

Former Member
0 Kudos

Hi Sanket,

We are alos trying similar feature. May be I can help you there. However , Can you let me know where did you get the latest version of SAP ICI WSDL file. That would be really helpful.

We are working on older version of this file , however not able to locate the latest version.

regards!

Sunil

Former Member
0 Kudos

Hello there,

we are stuck at the same problem. do you have any hint where to proceed to get a wcf service recognized by ici? the WSNavigator successful can call all our methods, but CRM cannot find them. so there is some mismatch in contract names or endpoint names - we cannot find out, so any help is appreciated. if you have a sample wsdl which is working i also would be very happy to receive that. my email: wf (at) voxtron.de

thanks

wolfgang

Former Member
0 Kudos

Hello,

Unfortunately ICI cant understand WCF. All ICI does it that it post SOAP messages or HTTP. So to make the .Net webservice work you will need to add a method to the contract that accepts Message class as input parameter and returns Message class as output.

Within that method you can then inspect the incoming SOAP packet and find out which method is called by ICI and take action accordingly.

When returning a response you will need to create an XML document conforming to the return structure and then send it back to the received AppUrl using the Events interface.

Hope this will give you a little idea.

Regards,

Sanket Banawalikar

Former Member
0 Kudos

Hi,

could you share your sample for the webservice?

Thanks