Creating a Basic Web Services Client in C Sharp Using ASP.NET Core

To create a simple Entitlement using the EntitlementOrderService wsdl, you will need to create a C# Console Application project with a Web Reference that contains an override function which specifies that requests are to use "Basic" HTTPS authentication, adding a new "Authorization" header with credentials of the form "Basic " plus the base-64-encoded "Name:Password" string.

Creating a Simple Entitlement for ASP.NET Core

1. In Visual Studio 2022 or later, create a new ASP.NET CORE WEB API project.
2. In the Solution Explorer, right-click the project icon and select Add > Service Reference.

Alternatively, you can also open the Connected Services and click Add a service reference.

3. Select WCF Web Service and click Next.
4. In the URI field, enter https://<siteID>.flexnetoperations.com/flexnet/services/EntitlementOrderService?wsdl and click Go.

Alternatively, enter https://<siteID>.flexnetoperations.com/flexnet/services to see a list of all available FlexNet Operations WSDLs.

5. Choose the service listed in the Services section to view the available APIs/operations.
6. Change the Namespace to EntitlementOrderServiceReference and click Next.
7. In the Specify the client options screen, select the check boxes Generate Synchronous Operations and Enable Data Binding. This allows you to generate both asynchronous and synchronous client operations.
8. Click Finish. The Solution Explorer window now shows the new EntitlementOrderService icon in the Connected Services folder.
9. Double-click the EntitlementOrderService icon, which opens the Object Browser.
10. Open the Reference.cs proxy class source file.
11. Search for the EntitlementOrderServiceInterfaceV5Client class and add the following code above it:

Copy
/// <summary>
/// Add credentials and endpoint headers here
/// </summary>
public partial class EntitlementOrderServiceInterfaceV5Client : System.ServiceModel.ClientBase<EntitlementOrderServiceReference.EntitlementOrderServiceInterfaceV5>, sEntitlementOrderServiceReference.EntitlementOrderServiceInterfaceV5
{
    static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials)
    {
        byte[] credentialBuffer = new System.Text.UTF8Encoding().GetBytes("***Username***" + ":" + "***Password***");
        var headers = new Dictionary<string, string>
            {
                {"Authorization", "Basic " + Convert.ToBase64String(credentialBuffer)}
            };
            
        var behavior = new AddHttpHeaderMessageEndpointBehavior(headers);
        serviceEndpoint.EndpointBehaviors.Add(behavior);

        clientCredentials.UserName.UserName = "***Username***";
        clientCredentials.UserName.Password = "***Password***";
    }
}
/// <summary>
/// define custom endpoint behavior
/// </summary>
public class AddHttpHeaderMessageEndpointBehavior : IEndpointBehavior
{
    private readonly IClientMessageInspector _httpHeaderMessageInspector;

    public AddHttpHeaderMessageEndpointBehavior(Dictionary<string, string> headers)
    {
        _httpHeaderMessageInspector = new HttpHeaderMessageInspector(headers);
    }

    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {

    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
        clientRuntime.ClientMessageInspectors.Add(_httpHeaderMessageInspector);
    }
                
    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
                
    }
        
    public void Validate(ServiceEndpoint endpoint)
    {

    }
}

/// <summary>
/// define customer message inspector
/// </summary>
public class HttpHeaderMessageInspector : IClientMessageInspector
{
    private readonly Dictionary<string, string> _headers;

    public HttpHeaderMessageInspector(Dictionary<string, string> headers)
    {
        _headers = headers;
    }

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

    }

    public object BeforeSendRequest(ref Message request, IClientChannel channel)
    {
        if (request.Properties.Count == 0 || request.Properties[HttpRequestMessageProperty.Name] == null)
        {
            request.Properties.Add(HttpRequestMessageProperty.Name, new HttpRequestMessageProperty());
        }
        var headersCollection = ((HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]).Headers;

        foreach (var header in _headers) headersCollection[header.Key] = header.Value;

        return null;
    }
}

12. Search for all occurrences of ***Username*** and ***Password***, using the correct credentials.
13. Search for the GetBindingForEndpoint method definition and replace it with the following code:

private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration endpointConfiguration)

Copy
private static System.ServiceModel.Channels.Binding GetBindingForEndpoint(EndpointConfiguration
                endpointConfiguration)
{
    if ((endpointConfiguration == EndpointConfiguration.EntitlementOrderServiceV5))
    {
        System.ServiceModel.BasicHttpsBinding result = new System.ServiceModel.BasicHttpsBinding();
        result.Security.Transport.ClientCredentialType = HttpClientCredentialType.Basic;
        result.MaxBufferSize = int.MaxValue;
        result.ReaderQuotas = System.Xml.XmlDictionaryReaderQuotas.Max;
        result.MaxReceivedMessageSize = int.MaxValue;
        result.AllowCookies = true;
        return result;
    }
    throw new System.InvalidOperationException(string.Format("Could not find endpoint with name 
        \'{0}\'.", endpointConfiguration));
}

14. Search for the GetEndpointAddress method definition and change the URL used to return the EndpointAddress from http to https.
15. Create a new Controller "EntitlementOrderController". Replace the code generated by the Visual Studio editor with the following code:

Copy
using EntitlementOrderServiceReference;
using Microsoft.AspNetCore.Mvc;

namespace ConsumeWSDLConnectedServices.Controllers
{
    [ApiController]
    [Route("EntitlementOrderController")]
    public class EntitlementOrderController : Controller
    {
        [Route("CreateSimpleEntitlement")]
        [HttpPost]
        public ActionResult CreateSimpleEntitlement()
        {
            EntitlementOrderServiceInterfaceV5Client entitlementOrderServiceInterface = new EntitlementOrderServiceInterfaceV5Client();

            // one and only simple entitlement
            createSimpleEntitlementRequestType createSimpleEntitlementRequestType = new createSimpleEntitlementRequestType();
            createSimpleEntitlementDataType[] seArray = new createSimpleEntitlementDataType[1];
            createSimpleEntitlementDataType se1 = new createSimpleEntitlementDataType();

            seArray[0] = se1;
            idType idtype = new idType();

            // make sure to change the Order ID for each test...

            idtype.id = "ExampleOrderID";
            se1.entitlementId = idtype;

            // make sure this is a real customer account

            se1.soldTo = "Atlas";

            // one and only line item

            createEntitlementLineItemDataType[] lineItems = new createEntitlementLineItemDataType[1];
            se1.lineItems = lineItems;
            lineItems[0] = new createEntitlementLineItemDataType();
            idtype = new idType();
            idtype.id = "ActID-Atlas-123456";
            lineItems[0].activationId = idtype;
            lineItems[0].numberOfCopies = "5";
            lineItems[0].startDateSpecified = true;
            lineItems[0].startDate = DateTime.Today;
            lineItems[0].expirationDateSpecified = true;
            lineItems[0].expirationDate = DateTime.Today.AddYears(1);

            licenseModelIdentifierType lm = new licenseModelIdentifierType();
            licenseModelPKType modelPk = new licenseModelPKType();

            // Add a License Model for the desired Product

            modelPk.name = "Embedded Counted";
            lm.primaryKeys = modelPk;
            lineItems[0].licenseModel = lm;
            lineItems[0].versionDate = DateTime.Today.Date;

            productIdentifierType ordId = new productIdentifierType();
            productPKType productPk = new productPKType();

            // Be sure to pick a real product and version

            productPk.name = "LH Full Access";
            productPk.version = "1.0";
            ordId.primaryKeys = productPk;
            lineItems[0].product = ordId;

            // this function is in the auto-generated Reference.cs code

            createSimpleEntitlementRequestType.simpleEntitlement = seArray;

            createSimpleEntitlementResponseType csert = entitlementOrderServiceInterface.createSimpleEntitlement(createSimpleEntitlementRequestType);

            if (csert.statusInfo.status != StatusType.SUCCESS)
            {
                Console.WriteLine("Drat! Failed: " + csert.statusInfo.reason);
            }
            else
            {
                Console.WriteLine("Success!");
            }

            return new JsonResult(csert);
        }
    }
}

16. Build and run the application.