| Back | Main view

How to build IMiS/Storage Connector SOAP Service C# client with WCF

Product:IMiS/Storage Connector SOAP Service
Release:3.2.1711
Date:02/09/2018

Case: IMiS/Storage Connector SOAP Service is a web service implemented with JAX-WS on Java. When implementing C# client with WCF be aware that WCF is not fully compatible with JAX-WS out of the box. This article provides an example C# client implementation with WCF using Digest authentication over SSL on our demo IMiS/Storage Connector SOAP Service site.

Description:

When building C# web service client one should follow this general steps:
1. Add service reference to your Visual Studio project
2. Configure webservice through code or configuration.
3. Create WCF client object that can call service.
4. Setup callback to validate a server certificate when using SSL.
5. Use client credentials when using Basic or Digest authentication.
6. Implement client code using web service API.

In the example we have configured binding and endpoint to the service through configuration. The important thing to notice is that we have disabled 'Expect: 100-continue' behavior through ServicePointManager since the service is not compatible with the client when binding security mode equals Transport and the client credential types are either Basic or Digest. Note that you limit the size of the SOAP messages on the binding through the maxBufferSize and maxReceivedSize and maxBufferPoolSize fields. In the source code we are using trivial implementation of server certificate validation. Proper server certificate validation should be implemented if needed. Username and password must be provided for client credentials. In the client code example we are storing a file to IMiS/ARChive server where storage, content type and file path must be provided.

App.config:

XML
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="IMiSStorageConnectorSOAPService_SSL_Digest"
maxBufferPoolSize="2147483647"
maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="Transport">
<transport clientCredentialType="Digest" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="https://extdemo1.imis.si:8443/iscsoapsvc-digest/service"
binding="basicHttpBinding"
bindingConfiguration="IMiSStorageConnectorSOAPService_SSL_Digest"
contract="ServiceReference1.ServicePort"
name="IMiSStorageConnectorSOAPService_SSL_Digest" />
</system.serviceModel>
<system.net>
<settings>
<servicePointManager expect100Continue="false"/>
</settings>
</system.net>
</configuration>
Source code:

C#
/// <summary>
/// Store local file as object on IMiS/ARC Storage Server.
/// </summary>
/// <param name="client">
/// An IMiS/Storage Connector SOAP service port client.
/// </param>
/// <param name="storage">
/// An IMiS/ARChive storage alias.
/// </param>
/// <param name="contentType">
/// The content type of the local file to be stored.
/// </param>
/// <param name="filePath">
/// The file path of the local file to be stored.
/// </param>
/// <returns>
/// The IMiS/ARC Storage Server object identifier.
/// </returns>
static string StoreObjectToIMiSARC(ServiceReference1.ServicePortClient client,
string storage, string contentType, string filePath)
{
// Store operation parameters
ServiceReference1.StoreObjectRequest storeRequest = new StoreObjectRequest();

// Profile into which this object should be saved
storeRequest.Storage = storage;

// TransferDisposition describes how objects will be transferred
// across the wire.
// TRANSFER_AS_STREAM: Transfer object body as binary stream in
// Data parameter of the Request/Response message
// (conforms to WS-I Basic Profile 1.0)
// TRANSFER_AS_ATTACHMENT: Transfer object as attachment
// conforming to WS-I Attachments Profile 1.0
storeRequest.TransferDisposition = ServiceReference1.ObjectTransferDisposition.TRANSFER_AS_STREAM;

// Describes the content of the stored object
storeRequest.ContentType = contentType;

// Read input file
FileStream fileStream = new FileStream(filePath, FileMode.Open);
storeRequest.Data = new byte[fileStream.Length];
fileStream.Read(storeRequest.Data, 0, storeRequest.Data.Length);
fileStream.Close();

// Execute the command. If call succeeds result holds unique
// object ID which need to be saved for future references
ServiceReference1.StoreObjectResponse storeResult = client.StoreObject(storeRequest);

// Response's ObjectID property holds new object unique identifier used
// for object retrieval
return storeResult.ObjectID;
}

/// <summary>
/// Verifies the remote Secure Sockets Layer (SSL) certificate used for authentication.
/// </summary>
/// <param name="client">
/// An IMiS/Storage Connector SOAP service port client.
/// </param>
/// <param name="certificate">
/// The certificate used to authenticate the remote party.
/// </param>
/// <param name="chain">
/// The chain of certificate authorities associated with the remote certificate.
/// </param>
/// <param name="policyErrors">
/// One or more errors associated with the remote certificate.
/// </param>
/// <returns>
/// <c>True</c> if the specified certificate is accepted for authentication; otherwise <c>False</c>.
/// </returns>
static bool ValidateRemoteCertificate(object sender, X509Certificate certificate,
X509Chain chain, SslPolicyErrors policyErrors)
{
// Validate server certificate is necessary!
return true;
}

/// <summary>
/// Stores object to IMiS/ARChive server using Digest authentication over SSL.
/// </summary>
static void SSLDigestAuthentication()
{
try
{
// Assign server certificate validation callback
ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

// Create service port client instance
ServiceReference1.ServicePortClient client = new ServiceReference1.ServicePortClient("IMiSStorageConnectorSOAPService_SSL_Digest");

// Create client credentials
client.ClientCredentials.HttpDigest.ClientCredential = new NetworkCredential(USERNAME, PASSWORD);
client.ClientCredentials.HttpDigest.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

// Store object to IMiS/ARChive server
StoreObjectToIMiSARC(client, STORAGE, CONTENTTYPE, FILEPATH);
}
catch (Exception ex)
{
Console.Out.WriteLine("ErrorMessage = {0}", ex.Message);
}
}
Related Documents:



| Back | Main view