techrefguide

28
Epicor ERP Epicor WCF Services Developer Guide 10.0.700

Upload: vmro

Post on 06-Dec-2015

27 views

Category:

Documents


5 download

DESCRIPTION

epicor

TRANSCRIPT

Epicor ERPEpicor WCF Services DeveloperGuide10.0.700

Disclaimer

This document is for informational purposes only and is subject to change without notice. This document and itscontents, including the viewpoints, dates and functional content expressed herein are believed to be accurate as of itsdate of publication. However, Epicor Software Corporation makes no guarantee, representations or warranties withregard to the enclosed information and specifically disclaims any applicable implied warranties, such as fitness for aparticular purpose, merchantability, satisfactory quality or reasonable skill and care. As each user of Epicor software islikely to be unique in their requirements in the use of such software and their business processes, users of this documentare always advised to discuss the content of this document with their Epicor account manager. All information containedherein is subject to change without notice and changes to this document since printing and other important informationabout the software product are made or published in release notes, and you are urged to obtain the current releasenotes for the software product. We welcome user comments and reserve the right to revise this publication and/ormake improvements or changes to the products or programs described in this publication at any time, without notice.The usage of any Epicor software shall be pursuant to an Epicor end user license agreement and the performance ofany consulting services by Epicor personnel shall be pursuant to Epicor's standard services terms and conditions. Usageof the solution(s) described in this document with other Epicor software or third party products may require the purchaseof licenses for such other products. Where any software is expressed to be compliant with local laws or requirementsin this document, such compliance is not a warranty and is based solely on Epicor's current understanding of such lawsand requirements. All laws and requirements are subject to varying interpretations as well as to change and accordinglyEpicor cannot guarantee that the software will be compliant and up to date with such changes. All statements ofplatform and product compatibility in this document shall be considered individually in relation to the products referredto in the relevant statement, i.e., where any Epicor software is stated to be compatible with one product and alsostated to be compatible with another product, it should not be interpreted that such Epicor software is compatiblewith both of the products running at the same time on the same platform or environment. Additionally platform orproduct compatibility may require the application of Epicor or third-party updates, patches and/or service packs andEpicor has no responsibility for compatibility issues which may be caused by updates, patches and/or service packsreleased by third parties after the date of publication of this document. Epicor® is a registered trademark and/ortrademark of Epicor Software Corporation in the United States, certain other countries and/or the EU. All othertrademarks mentioned are the property of their respective owners. Copyright © Epicor Software Corporation 2014.All rights reserved. No part of this publication may be reproduced in any form without the prior written consent ofEpicor Software Corporation.

10.0.700

Revision: July 03, 2014 12:16 p.m.

Total pages: 28

sys.ditaval

Contents

Introduction............................................................................................................................4Audience.........................................................................................................................................................4

Prerequisites....................................................................................................................................................4

Conventions....................................................................................................................................................4

Overview.................................................................................................................................5When to Use HTTP Transport...........................................................................................................................5

When to Use the TCP Transport.......................................................................................................................5

HTTP Transport.......................................................................................................................6WCF Services Example.....................................................................................................................................6

Create the Visual Studio Project................................................................................................................6

Add the Web Service References...............................................................................................................7

Add Helper Classes...................................................................................................................................8

Add Functionality to the Program Class...................................................................................................11

Code the Main Method..........................................................................................................................14

Setting Up SSL......................................................................................................................20Create Site Binding........................................................................................................................................20

Connect the Application Server......................................................................................................................24

Enable HTTP Endpoints........................................................................................................25Update the Web.Config File...........................................................................................................................25

BasicHTTPBinding Explanation........................................................................................................................25

WSHTTPBinding Explanation..........................................................................................................................26

3Epicor ERP | 10.0.700

ContentsEpicor WCF Services Developer Guide

Introduction

Welcome to the Epicor WCF-Services Developer Guide. This document describes how to consume the EpicorWCF-Services, how to configure the web services for different scenarios, and other information developers mayfind useful when working with Epicor Web Services.

This guide is written for the .NET 4 platform.

Audience

This guide is intended for developers responsible for integrating with Epicor ERP using web services. By leveragingweb services, developers can make Epicor data available for use in third party applications, custom storefrontapplications, and other purposes. These web services also can move Epicor data into Java or other programmingenvironments.

Prerequisites

This document assumes you have a working knowledge of C#, Visual Studio 2012, .NET 4.0, and InternetInformation Services (IIS). You should also understand the basic concepts behind web services and WCF.

This guide assumes you have already installed your Epicor application server, so application server installationinstructions are not included in this document. This document also assumes you have a configured Epicor clientapplication on your local development machine. You will need access to the client assemblies to complete somecoding projects.

Conventions

This guide uses the following conventions.

• When this document refers to Internet Information Services (IIS), it refers to the server where you installedthe Epicor application server.

• Code samples appear in the follow font style:

static void Main(string[] args){ string myString = "Test";

Epicor ERP | 10.0.7004

Epicor WCF Services Developer GuideIntroduction

Overview

The Epicor WCF services support two transport mechanisms: net.tcp and http/ https.

Each of these mechanism requires you follow a different approach when you use them. You also need to properlyconfigure the application server’s Web.Config file.

When to Use HTTP Transport

Microsoft states the following about when you should use HTTP Transport:

HTTP is a request/response protocol between clients and servers. The most common application consists ofWeb-browser clients that communicate with a Web server. The client sends a request to a server, which listensfor client request messages. When the server receives a request, it returns a response, which contains the statusof the request. If successful, optional data, such as a Web page, an error message, or other information is returned.

In WCF, the HTTP transport binding is optimized for interoperability with legacy non-WCF systems. If allcommunicating parties are using WCF, the TCP-based binding is faster.

When to Use the TCP Transport

Microsoft states the following about when you should use TCP Transport:

TCP is a connection-based, stream-oriented delivery service with end-to-end error detection and correction.Connection-based means that a communication session between hosts is established before exchanging data.A host is any device on a TCP/IP network identified by a logical IP address.

TCP provides reliable data delivery and ease of use. Specifically, TCP notifies the sender of packet delivery,guarantees that packets are delivered in the same order in which they are sent, retransmits lost packets, andensures that data packets are not duplicated. Note that this reliable delivery applies between two TCP/IP nodes,and is not the same thing as WS-ReliableMessaging, which applies between endpoints, no matter how manyintermediate nodes they may include. The WCF TCP transport is optimized for the scenario where both ends ofthe communication are using WCF. This binding is the fastest WCF binding for scenarios that involve communicatingbetween different machines.

5Epicor ERP | 10.0.700

OverviewEpicor WCF Services Developer Guide

HTTP Transport

In WCF, you specify how to transfer data across a network between endpoints through a binding, and eachbinding is made up of a sequence of binding elements.

For HTTP Transport, this document explores BasicHttpBinding and WSHttpBinding.

• BasicHttpBinding - Used when you communicate with ASMX-based web services, web clients, and otherservices that conform to the WS-I Basic Profile 1.1 (Web Services Interoperability Organization, 2004).

• WSHttpBinding - Supports the SOAP 1.2 and WS-Addressing specifications.

By default BasicHttpBinding sends data in plain text, while WSHttpBinding sends it in an encrypted and securedmanner.

WCF Services Example

This section describes the process through which Epicor web services are consumed. This process is illustratedthrough an ABCCode service example.

You will create a sample C# project that consumes the ABCCode service using either BasicHttpBinding orWSHttpBinding. To illustrate this example, the Epicor application server is located on a machine named ‘localhost’and the application name is ‘ERP100500’. When you see these values in the code samples, replace them withvalues that match your environment.

Requirements

To complete this example, set up the following items:

• IIS needs to be configured for SSL. If you have not done this, review the Setting Up SSL section later in thisguide.

• Your application server must also be configured to enable the BasicHttpBinding and WSHttpBinding endpoints.For information on setting up your application server to use these two forms of HTTP transport, review theEnable HTTP Endpoints section later in this guide.

Create the Visual Studio Project

1. Launch Microsoft® Visual Studio

®.

2. Select the File > New > Project menu item.

3. In the New Project dialog box, verify Visual C# is selected in the tree view.

4. Next in the Detail panel, select Console Application.

5. For the project Name, enter AbcCodeServiceClient.

6. Select the location where you will save the project.

7. Click OK.

Epicor ERP | 10.0.7006

Epicor WCF Services Developer GuideHTTP Transport

Add the Web Service References

You need to reference the SessionMod and AbcCode services. The SessionMod service creates a session on theserver that persists between method calls. This service also changes certain session properties, such as the companyor site you are working against. The AbcCode service maintains ABC codes.

1. In the Solution Explorer, right-click the AbcCodeServiceClient project item and select the Add> ServiceReference… menu item.The Add Service Reference dialog box displays.

2. In the Address field, enter the URL to your SessionMod service. For this example, the URL is thehttp://localhost/ERP100500/ICE/Lib/SessionMod.svc value.

3. Click Go.The details for the service display.

4. For the Namespace field, enter Epicor.SessionModSvc.

5. Click OK.The reference is added to your project.

6. Repeat steps 1-5 again. This time add a reference to the AbcCode service. The address for this service islike http://localhost/ERP100500/Erp/BO/AbcCode.svc, and you use a namespace value ofEpicor.AbcCodeSvc.

7Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

Add Helper Classes

One feature of the Epicor application server is the client can institute a session on the server. Any session levelproperties the user may set persist between each server call as long as each call uses the same session ID. To dothis, you provide a SessionInfo SOAP header. You can provide this header through multiple methods.

The process described below does not require you take a dependency on any Epicor assemblies. These steps notewhere you could use the Epicor provided classes in place of the classes you enter through code.

1. In the Solution Explorer, right-click the AbcCodeServiceClient project item.

2. Select the Add > Class… menu item.The Add New Item dialog box displays. On the List view, the Class item should be selected by default.

3. Next in the Name field, enter CustomMessageInspector.

4. Click Add.

5. Return to the Solution Explorer and click on the CustomMessageInspector.cs file.This opens the file in the Editor window.

6. At the top of the file you see the standard using statements. You need to add the following custom usingstatements to this list:

using System.ServiceModel.Channels;using System.ServiceModel.Description;using System.ServiceModel.Dispatcher;

7. Visual Studio creates an empty class for you named CustomMessageInspector. However before you doany work on it, add two other classes to this file.

class CustomMessageInspector { }

Directly beneath the closing curly brace for the CustomMessageInspector class, add these classes:

class SessionInfoHeader{

}

class HookServiceBehavior{

}

8. You next work on the SessionInfoHeader. This class represents the session information SOAP header item.

a. Your SessionInfoHeader must inherit from the System.ServiceModel.Channels.MessageHeaderclass. You have already added a using statement for the System.ServiceModel.Channels namespace,so next indicate this class inherits from MessageHeader:

class SessionInfoHeader: MessageHeader

b. MessageHeader is an abstract class, so it contains two properties (Name and Namespace) and a method(OnWriteHeaderContents). You override these properties to implement them. The

Epicor ERP | 10.0.7008

Epicor WCF Services Developer GuideHTTP Transport

OnWriteHeaderContents method is called when the header contents are serialized. You write thecontents of the header through this code block:

protected override void OnWriteHeaderContents(System.Xml.XmlDictionaryWriter writer, MessageVersion messageVersion){ writer.WriteElementString("SessionID", @"http://schemas.datacontract.org/2004/07/Epicor.Hosting", SessionId.ToString()); writer.WriteElementString("UserID", @"http://schemas.datacontract.org/2004/07/Epicor.Hosting", EpicorUserId);}

public override string Name{ get { return "SessionInfo"; }}

public override string Namespace

{ get { return "urn:epic:headers:SessionInfo"; }}

c. To complete this class, add two properties that store the user’s Epicor session Id and Epicor user Id:

public Guid SessionId { get; set; }public string EpicorUserId { get; set; }

9. Next update the HookServiceBehavior class. This class implements theSystem.ServiceModel.Description.IEndpointBehavior interface. You can then implement methods toextend run-time behavior for an endpoint in the client application. The interface exposes four methods:

• AddBindingParameters -- Passes custom data at runtime to enable bindings to support custom behavior.

• ApplyClientBehavior -- Modifies, examines, or inserts extensions to an endpoint in a client application.

• ApplyDispatchBehavior -- Modifies, examines, or inserts extensions to endpoint-wide execution in aservice application.

• Validate -- Confirms a ServiceEndpoint meets specific requirements. Use this method to ensure anendpoint has a certain configuration setting enabled, supports a particular feature, and uses otherrequirements.

You must implement all four methods, but you only add code to the ApplyClientBehavior method. Dothe following:

a. Specify that the HookServiceBehavior implements the IEndpointBehavior interface.

class HookServiceBehavior : IEndpointBehavior

b. After the opening curly brace, add two private variables that hold the user’s Session ID and Epicor UserID.

class HookServiceBehavior : IEndpointBehavior{ private Guid _sessionId; private string _epicorUserId;

c. Now create a constructor method for the class that takes for parameters a Guid and a string. Thisconstructor then uses those values to set the class level variables you created.

public HookServiceBehavior(Guid SessionId, string EpicorUserId){

9Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

_sessionId = SessionId; _epicorUserId = EpicorUserId;}

Tip You may notice that Visual Studio displays errors that refer to code in the ApplyClientBehaviormethod. You can ignore these messages, as they will stop once you implement theCustomMessageInspector class.

d. Provide implementations for the four methods defined by the interface.

public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters){ }

public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime){ clientRuntime.ClientMessageInspectors.Add(new CustomMessageInspector(_sessionId, _epicorUserId));}

public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { }

public void Validate(ServiceEndpoint endpoint) { }

10. Now implement the CustomMessageInspector class. This class adds the SessionInfo header to theoutgoing request headers.

a. Specify the CustomMessageInspector class implements the IClientMessageInspector interface. Thisinterface defines a message inspector object that can be added to the MessageInspectors collectionto view or modify messages.

class CustomMessageInspector : IClientMessageInspector

b. Add two private class level variables that hold the Epicor session Id and user Id.

class CustomMessageInspector : IClientMessageInspector{

private Guid _sessionID; private string _epicorUserId;

c. Add a constructor method for the class that uses for parameters a Guid and a string. Assign their valuesto the two class level variables you added.

public CustomMessageInspector(Guid SessionId, string EpicorUserId){ _sessionID = SessionId; _epicorUserId = EpicorUserId;}

d. Enter the two methods required for the IClientMessageInspector interface. In this example, only addcode to the BeforeSendRequest method, as this method is where you place the SessionInfo headerinformation.

public void AfterReceiveReply(ref Message reply, object correlationState){ }

public object BeforeSendRequest(ref Message request, System.ServiceModel.IClientChannel channel){

Epicor ERP | 10.0.70010

Epicor WCF Services Developer GuideHTTP Transport

if (_sessionID != null && _sessionID != Guid.Empty) { var sessionHeader = new SessionInfoHeader() { SessionId = _sessionID, EpicorUserId = _epicorUserId }; request.Headers.Add(sessionHeader); } return request;}

At this point your helper classes are complete, but the project does not actually function. However you can runa test build of the project to make sure you don’t have build errors. If you do, review these steps again to correctthese errors.

Add Functionality to the Program Class

You next add code to the Program class provided in the Program.cs code file. You add three helper methods tothis class that are called from the Main method. These methods do the work of creating an instance of the serviceclient classes you defined when you added the service references.

1. Since this project demonstrates the ability to call into the Epicor services using either BasicHttpBinding orWSHttpBinding, you start by defining an enumeration that specifies which binding to use.

class Program{ private enum EndpointBindingType { SOAPHttp, BasicHttp }

2. You next code the first two helper methods. These methods programmatically create the endpoint bindings.

Tip You can also configure the endpoint bindings through the application configuration file(app.config). For this example, you configure these endpoint bindings in code.

a. First add the using statements. Visual Studio has already added the standard using statements, so youadd the following using statements to this list:

using System.Net;using System.Reflection;using System.ServiceModel;using System.ServiceModel.Channels;using AbcCodeServiceClient.Epicor.AbcCodeSvc;using AbcCodeServiceClient.Epicor.SessionModSvc;

b. Now enter the GetWsHttpBinding method. This method can be added immediately after the Mainmethod.

private static WSHttpBinding GetWsHttpBinding(){ var binding = new WSHttpBinding();

const int maxBindingSize = Int32.MaxValue; binding.MaxReceivedMessageSize = maxBindingSize; binding.ReaderQuotas.MaxDepth = maxBindingSize; binding.ReaderQuotas.MaxStringContentLength = maxBindingSize; binding.ReaderQuotas.MaxArrayLength = maxBindingSize; binding.ReaderQuotas.MaxBytesPerRead = maxBindingSize; binding.ReaderQuotas.MaxNameTableCharCount = maxBindingSize;

11Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

binding.Security.Mode = SecurityMode.Message; binding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;

return binding;}

c. Name the second method GetBasicHttpBinding; this method creates a new, properly configuredinstance of the BasicHttpBinding class.

Notice this method is similar to the first method. Unfortunately these two bindings inherit from differentclasses and the ReaderQuotas property is defined on each base class instead of common base classfrom which they both inherit. Add the following method directly below the GetWsHttpBinding method.

public static BasicHttpBinding GetBasicHttpBinding(){

var binding = new BasicHttpBinding();

const int maxBindingSize = Int32.MaxValue; binding.MaxReceivedMessageSize = maxBindingSize; binding.ReaderQuotas.MaxDepth = maxBindingSize; binding.ReaderQuotas.MaxStringContentLength = maxBindingSize; binding.ReaderQuotas.MaxArrayLength = maxBindingSize; binding.ReaderQuotas.MaxBytesPerRead = maxBindingSize; binding.ReaderQuotas.MaxNameTableCharCount = maxBindingSize; binding.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential; binding.Security.Message.ClientCredentialType = BasicHttpMessageCredentialType.UserName;

return binding;

}

Notice this code first creates a new instance of the binding. It then sets the maximum values for themessage size and reader quotas. The reader quotas element defines the constraints on the complexityof the SOAP messages processed by endpoints configured through this binding. With the Epicorapplication, you can retrieve large record sets.

The code next specifies the security mode the binding will use:

• For the BasicHttpBinding, set it to TransportwithMessageCredential. This mode indicates youuse https and that the service is configured with a certificate. SOAP message security provides theclient authentication.

• For the WSHttpBinding, set the security mode to Message as the WSHttpBinding encrypts itsmessages by default.

For both bindings, set the client credential type to UserName to indicate you want to include a UserNametoken in the header.

3. Now add the last helper method – GetClient. This method creates an instance of the client classes. Addthe following method directly after the GetBasicHttpBinding method.

private static TClient GetClient<TClient, TInterface>( string url, string username, string password, EndpointBindingType bindingType) where TClient : ClientBase<TInterface> where TInterface : class{

Epicor ERP | 10.0.70012

Epicor WCF Services Developer GuideHTTP Transport

Binding binding = null; TClient client;

var endpointAddress = new EndpointAddress(url);

switch (bindingType) { case EndpointBindingType.BasicHttp: binding = GetBasicHttpBinding(); break; case EndpointBindingType.SOAPHttp: binding = GetWsHttpBinding(); break; }

client = (TClient)Activator.CreateInstance(typeof(TClient), binding, endpointAddress);

if (!string.IsNullOrEmpty(username) && (client.ClientCredentials != null)) { client.ClientCredentials.UserName.UserName = username; client.ClientCredentials.UserName.Password = password; }

return client;}

This code first creates an EndpointAddress instance that represents the URL of the service you are calling.The code then creates a binding based upon the EndpointBindingType passed in (you defined theEndpointBindingType enumeration in step 1). Once the code has the EndpointAddress and binding, it createsan instance of the client class. Lastly this code assigns the user name and password to the ClientCredentialsinstance on the client class.

You can also add a couple items to this code that help correct errors. If you receive operation timeout errorswhen calling a service, adjust the timeout values. A binding has four timeout values:

• OpenTimeout

• CloseTimeout

• ReceiveTimeout

• SendTimeout

By default, each has a value of one minute. If you receive errors like “The open operation did not complete withinthe allotted timeout…”, the service is hitting one of these timeouts. To correct this error, adjust the timeoutvalues on the binding. Place this code immediately after the ‘switch(bindingType)’ block:

TimeSpan operationTimeout = new TimeSpan(0, 12, 0); binding.CloseTimeout = operationTimeout; binding.ReceiveTimeout = operationTimeout; binding.SendTimeout = operationTimeout; binding.OpenTimeout = operationTimeout;

In the above example, notice you set the timeout values to twelve minutes.

You may need to make another code change to take into account the DNS identity difference between the serviceURL and the identity specified in the certificate used by the web server. This code handles error messages similarto the following:

“Identity check failed for outgoing message. The expected DNS identity of the remote endpoint was 'l303415'but the remote endpoint provided DNS claim 'L303415.americas.epicor.net'. If this is a legitimate remote endpoint,you can fix the problem by explicitly specifying DNS identity 'L303415.americas.epicor.net' as the Identity propertyof EndpointAddress when creating channel proxy.”

13Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

You can resolve this error in two ways. One way is to change the service URL so it uses the fully qualified machinename. You can also specify a DnsEndpointIdenity object to the EndpointAddress you created. To do this,replace the line:

var endpointAddress = new EndpointAddress(url);

With this line:

DnsEndpointIdentity endpointIdentity = new DnsEndpointIdentity("L303415.americas.epicor.net");var endpointAddress = new EndpointAddress(new Uri(url), endpointIdentity);

You will also need to add a reference to the System.IdentityModel assembly.

Code the Main Method

Now code the Main method and call the Epicor services. This example demonstrates how to initiate a serversession and associate that session with your server calls. It also demonstrates how to create, save , modify, anddelete a record.

1. If you use a self-signed certificate in IIS, be sure to include the following code. This code speeds up calls tothe services.

ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => { return true; };

This code tells the ServicePointManager (a class that provides connection management for HTTPconnections) to validate the server certificate. This prevents the method from trying to validate the certificatewith the known authorities.

2. Next create a variable that is an instance of the EndpointBindingType you created earlier. This instancedetermines which endpoint binding to use at runtime. You can toggle the value assigned to this variable totest the two bindings:

EndpointBindingType bindingType = EndpointBindingType.SOAPHttp;

3. Now create two variables that hold the Epicor User ID and Password. Set the value of these variables tomatch a valid User ID in your Epicor application.

Tip This example uses a plain string to hold the password. In production code, you store the passwordthough a SecureString instance.

string epicorUserID = "manager";string epiorUserPassword = "manager";

4. Next use code to determine what scheme will connect (HTTP vs. HTTPS). You also enter an UriBuilder codeline that creates the URL for the services.

In the constructor for the UriBuilder, be sure to enter the name of the machine that hosts your servicesinstead of “localhost”.

string scheme = "http";if (bindingType == EndpointBindingType.BasicHttp){ scheme = "https";}

UriBuilder builder = new UriBuilder(scheme, "localhost");

Epicor ERP | 10.0.70014

Epicor WCF Services Developer GuideHTTP Transport

5. Now add instances of the two service client classes created by Visual Studio; these classes were createdwhen you added the service references in Step 2. Before creating each instance, set the Path property ofthe UriBuilder to the path of the service.

In this example code, the Epicor 10 appserver name is “ERP100500”; replace this value with your appservername.

builder.Path = "ERP100500/Ice/Lib/SessionMod.svc";SessionModSvcContractClient sessionModClient = GetClient<SessionModSvcContractClient, SessionModSvcContract>( builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);

builder.Path = "ERP100500/Erp/BO/AbcCode.svc";ABCCodeSvcContractClient abcCodeClient = GetClient<ABCCodeSvcContractClient, ABCCodeSvcContract>( builder.Uri.ToString(), epiorUserPassword, epicorUserID, bindingType);

6. Now use the services. First call the SessionModSvc Login method to establish a session in the appserver.This returns a Guid that identifies the session. Then create an instance of the HookServiceBehavior classfor each client instance, passing it to the Guid you receive. This adds the SessionInfo header to eachsubsequent call.

Guid sessionId = Guid.Empty;sessionId = sessionModClient.Login();

sessionModClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));abcCodeClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));

7. Make calls to the AbcCodeSvc service. First create an instance of an empty ABCCodeTableset to pass intothe service. Then call the GetNewABCCode method to create a new ABCCode record.

This call returns a new row in the tableset with default values, but it does not save the row to the database.When you call a “GetNew” methods on the Epicor services, the row should return with the RowMod fieldset to “A”. The code uses this to select a new row from the ABCCode table in the tableset.

var ts = new ABCCodeTableset();abcCodeClient.GetNewABCCode(ref ts);var newRow = ts.ABCCode.Where(n => n.RowMod.Equals("A", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

if (newRow != null){

}

8. You can now set the required fields and call the Update method on the service to save the record.

In this example, the code sets the ABCCode field for the new row to a “G” value. However for your code,use a value that does not exist. This code goes between the curly braces after the if (newRow != null)statement you added in the previous step.

newRow.ABCCode = "G";newRow.CountFreq = 30;newRow.StockValPcnt = 100;

15Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

abcCodeClient.Update(ref ts);

9. Since you saved the record, you next fetch it from the server. This example demonstrates your record wassaved by the previous code. Replace the “G” in the call to GetByID with the code you entered in the previousstep.

ts = null;ts = abcCodeClient.GetByID("G");if (ts != null && ts.ABCCode.Any()){}

10. Next update some values on the record and save it back to the server again. This code goes inside the curlybraces that appear after the if(ts != null && ts.ABCCode.Any()) code added in the previous step.

This code example demonstrates two important concepts:

• First, server business logic often requires both the ‘before’ and ‘updated’ versions of the row be sent.This requires you make a copy of the row and then add it to the table before making changes.

• Second, when you update an existing record, set the RowMod field in the row to a “U” value. If youdo not do this, your changes are not saved. After saving the change, you null out the tableset and callGetByID again to demonstrate the record was updated.

ABCCodeRow backupRow = new ABCCodeRow();var fields = backupRow.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);foreach(var field in fields){ if (field.PropertyType == typeof(System.Runtime.Serialization.ExtensionDataObject)) { continue; } var fieldValue = field.GetValue(ts.ABCCode[0]); field.SetValue(backupRow, fieldValue);}

ts.ABCCode.Add(backupRow);ts.ABCCode[0].CountFreq = 45;ts.ABCCode[0].RowMod = "U";abcCodeClient.Update(ref ts);

ts = null;ts = abcCodeClient.GetByID("G");if (ts != null && ts.ABCCode.Any()){ Console.WriteLine("CountFreq = {0}", ts.ABCCode[0].CountFreq);}

11. To finish the AbcCodeSvc service, delete the record. Place the following code immediately after the call toConsole.WriteLine and inside the curly braces that surround it.

To delete a record, set the RowMod field to a “D” value and call the Update method. Again you try to callthe GetByID method to retrieve the record. This time no record should exist, so a “record not found” errorshould get thrown by the application server.

The following code demonstrates wrapping the service call in a try/catch block. You should always codedefensively and have code that can handle exceptions that may occur when calling the application server.Other possible values for the ExceptionKindValue are “ServerException”, “BLException”,

Epicor ERP | 10.0.70016

Epicor WCF Services Developer GuideHTTP Transport

“SqlException”, “DuplicateRecord”, “ConversionPending”, “VersionMismatch” and“UnknownException”.

ts.ABCCode[0].RowMod = "D";abcCodeClient.Update(ref ts);

try{ ts = abcCodeClient.GetByID("G");}catch (FaultException<Epicor.AbcCodeSvc.EpicorFaultDetail> ex){ if (ex.Detail.ExceptionKindValue.Equals("RecordNotFound", StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("Record deleted."); } else { Console.WriteLine(ex.Message); }}

12. Lastly, call the LogOut method on the SessionModSvc. This releases the server session and makes sureyou are not needlessly consuming license seats.

This code goes after the closing curly brace that is tied to the “if(newRow != null)” block you added instep 7:

if (sessionId != Guid.Empty){ sessionModClient.Logout();}Console.ReadLine();

This completes the code for the Main method. You can now compile it in Visual Studio by selecting the Build >Build Solution option. Correct compilation errors. Run the code by selecting the Debug > Start Debuggingmenu option. Remember you can change the value of the bindingType variable to test the BasicHttpBinding andWSHttpBinding endpoint bindings.

The full code for the Main method displays below for your reference:

static void Main(string[] args){ ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, errors) => { return true; };

EndpointBindingType bindingType = EndpointBindingType.SOAPHttp;

string epicorUserID = "manager"; string epiorUserPassword = "Epicor123";

string scheme = "http"; if (bindingType == EndpointBindingType.BasicHttp) { scheme = "https"; }

UriBuilder builder = new UriBuilder(scheme, "localhost");

builder.Path = "ERP100500/Ice/Lib/SessionMod.svc"; SessionModSvcContractClient sessionModClient = GetClient<SessionModSvcContractClient, SessionModSvcContract>(

17Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);

builder.Path = "ERP100500/Erp/BO/AbcCode.svc"; ABCCodeSvcContractClient abcCodeClient = GetClient<ABCCodeSvcContractClient, ABCCodeSvcContract>( builder.Uri.ToString(), epicorUserID, epiorUserPassword, bindingType);

Guid sessionId = Guid.Empty; sessionId = sessionModClient.Login();

sessionModClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID)); abcCodeClient.Endpoint.EndpointBehaviors.Add(new HookServiceBehavior(sessionId, epicorUserID));

var ts = new ABCCodeTableset(); abcCodeClient.GetNewABCCode(ref ts);

var newRow = ts.ABCCode.Where(n => n.RowMod.Equals("A", StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault();

if (newRow != null) { newRow.ABCCode = "G"; newRow.CountFreq = 30; newRow.StockValPcnt = 100; abcCodeClient.Update(ref ts);

ts = null; ts = abcCodeClient.GetByID("G"); if (ts != null && ts.ABCCode.Any()) { ABCCodeRow backupRow = new ABCCodeRow(); var fields = backupRow.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public); foreach(var field in fields) { if (field.PropertyType == typeof(System.Runtime.Serialization.ExtensionDataObject)) { continue; }

var fieldValue = field.GetValue(ts.ABCCode[0]); field.SetValue(backupRow, fieldValue); } ts.ABCCode.Add(backupRow);

ts.ABCCode[0].CountFreq = 45; ts.ABCCode[0].RowMod = "U"; abcCodeClient.Update(ref ts);

ts = null; ts = abcCodeClient.GetByID("G"); if (ts != null && ts.ABCCode.Any()) { Console.WriteLine("CountFreq = {0}", ts.ABCCode[0].CountFreq);

Epicor ERP | 10.0.70018

Epicor WCF Services Developer GuideHTTP Transport

ts.ABCCode[0].RowMod = "D"; abcCodeClient.Update(ref ts);

try { ts = abcCodeClient.GetByID("G"); } catch (FaultException<Epicor.AbcCodeSvc.EpicorFaultDetail> ex) { if (ex.Detail.ExceptionKindValue.Equals("RecordNotFound", StringComparison.InvariantCultureIgnoreCase)) { Console.WriteLine("Record deleted."); } else { Console.WriteLine(ex.Message); } } } } }

if (sessionId != Guid.Empty) { sessionModClient.Logout(); } Console.ReadLine();}

19Epicor ERP | 10.0.700

HTTP TransportEpicor WCF Services Developer Guide

Setting Up SSL

You have two options for setting up SSL in Internet Information Services (IIS):

• Obtain an SSL certificate from a known certificate authority (CA) such as VeriSign or GeoTrust.

• Create a self-signed certificate through the IIS Management console.

The following steps outline how to configure IIS to use a self-signed certificate.

Create Site Binding

1. Open the Internet Information Services (IIS) Manager console. Click Start > All Programs >Administrative Tools > Internet Information Services (IIS) Manager.

2. Navigate to the tree view; select the server node and then double-click the Server Certificates icon in thelist view:

3. Now from the Actions panel, click the "Create Self-Signed Certificate" option:

Epicor ERP | 10.0.70020

Epicor WCF Services Developer GuideSetting Up SSL

4. In the Create Self-Signed Certificate dialog box, enter a name for the certificate such as Epicor-Dev.

5. Click OK.The certificate is created.

6. In the Server Certificates panel, right-click your new certificate; from the context menu, select the Viewoption.

7. Now in the certificate dialog, select the Details tab.

8. Highlight the Subject property. Write down this value, as you will need it later.

9. You next create an SSL Binding.

a. Select a site in the tree view (for example, ‘Default Web Site’).

b. Now in the Actions pane, select the Bindings option.

This launches the Site Bindings editor. Use this window to create, edit, and delete bindings for yourWeb site.

21Epicor ERP | 10.0.700

Setting Up SSLEpicor WCF Services Developer Guide

c. To add your new SSL binding, click the Add… button.

d. The default settings for a new binding are set to HTTP on port 80. From the Type drop-down list, selectthe https option.

e. From the SSL Certificate drop-down list, select the certificate you created in the previous steps.

f. To save your new binding, click OK.

10. Now verify the SSL binding works.

a. In the Actions pane, under the Browse Web Site section, click the link associated with the https binding.

Epicor ERP | 10.0.70022

Epicor WCF Services Developer GuideSetting Up SSL

b. Internet Explorer (IE) 7 and above will display an error page. Click the Continue to this website (notrecommended) link.

Tip This error occurs because the self-signed certificate was issued by your computer, not by atrusted Certificate Authority (CA). Internet Explorer 7 and above will trust the certificate if you addit to the list of Trusted Root Certification Authorities in the certificates store on the localcomputer or in Group Policy for the domain.

c. You should see a page similar to this example:

23Epicor ERP | 10.0.700

Setting Up SSLEpicor WCF Services Developer Guide

Connect the Application Server

Now that you have IIS configured to use SSL, you make your appserver aware of this certificate.

1. In Notepad open the Web.config file associated with you application server.

2. Locate the system.serviceModel/behaviors/serviceBehaviors/behavior/serviceCredentials element.

3. Add a serviceCertificate element to the serviceCredentials element. The serviceCertificate element lookslike the following:

<serviceCertificate findValue="L303415.americas.epicor.net" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />

4. Change the findValue attribute to be the subject value you noted in the previous section.

5. Save the Web.config file.

Epicor ERP | 10.0.70024

Epicor WCF Services Developer GuideSetting Up SSL

Enable HTTP Endpoints

If you need clients to connect to your Epicor application server using HTTP, configure endpoint bindings in yourweb.config file so they use this method of transport. The following topics describe how you enable HTTP endpoints.

Update the Web.Config File

This section describes how to configure the BasicHttpBinding to use the https and the WSHttpBinding to useplain http secured through X509 certificates.

1. Open the web.config for your application server in Notepad or a similar text editor.

2. Locate the system.serviceModel/bindings section. If they do not exist, add two bindings to this section.

<basicHttpBinding> <binding name="BasicHttp" maxReceivedMessageSize="2147483647"> <security mode="TransportWithMessageCredential"><message clientCredentialType="UserName" /> </security> <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxStringContentLength="2147483647" /> </binding> </basicHttpBinding> <wsHttpBinding> <binding name="SOAPHttp" maxReceivedMessageSize="2147483647"> <security mode="Message"> <message clientCredentialType="UserName" /> </security> <readerQuotas maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxDepth="2147483647" maxStringContentLength="2147483647" /> </binding> </wsHttpBinding>

3. Locate the system.serviceModel/protocolMapping section and add your two endpoints:

<remove scheme="https" /> <add scheme="https" binding="basicHttpBinding" bindingConfiguration="BasicHttp" /> <remove scheme="http" /> <add scheme="http" binding="wsHttpBinding" bindingConfiguration="SOAPHttp" />

4. Save the web.config file.

BasicHTTPBinding Explanation

Since BasicHttpBinding communicates in plain text, make sure it uses the SSL protocol.

You do this by specifying transport security; this ensures the communication is encrypted. You also need toprovide a username/password token to specify a security mode of “TransportWithMessageCredential”. By

25Epicor ERP | 10.0.700

Enable HTTP EndpointsEpicor WCF Services Developer Guide

setting the message client credential type to “UserName”, the client must authenticate the server using aUserName credential.

The reader quotas element of the binding defines the constraints on the complexity of the SOAP messagesprocessed by the configured binding endpoints. Because you can retrieve large records through the Epicorapplication, it is recommended you set these values to their maximum.

WSHTTPBinding Explanation

If you use WSHttpBinding, specify the message is encrypted by default. You can then use http to communicatewith the server.

Do this by indicating the security mode is "message", as security is provided using SOAP message security. Bydefault, the SOAP body is Encrypted and Signed. This requires that an SSL certification is specified in thesystem.serviceModel/behaviors/serviceBehaviors/behavior/serviceCredentials element in your web.config file(review the Setting Up SSL section for more information). You specify the client credential type is a usernameand you also specify the same reader quotas as in the BasicHttpBinding.

Epicor ERP | 10.0.70026

Epicor WCF Services Developer GuideEnable HTTP Endpoints

Index

B

basichttpbinding 25

C

conventions 4

H

helper classes, add 8http endpoints, enable 25http endpoints, web.config 25http transport 6http transport, when to use 5

M

main method 14main method, full code example 17

P

prerequisites 4

program class, add functionality 11

S

ssl set up 20ssl set up, connect application server 24ssl set up, site binding 20

T

tcp transport, when to use 5

V

visual studio project, create 6

W

wcf services example 6web services references, add 7wshttpbinding 26

27Epicor ERP | 10.0.700

IndexEpicor WCF Services Developer Guide

Additional information is available at the Education andDocumentation areas of the EPICweb Customer Portal. To access

this site, you need a Site ID and an EPICweb account. To create anaccount, go to http://support.epicor.com.