Skip to main content

Connecting via SOAP

This guide covers the three supported methods for connecting a .NET 10 application to the ECGridOS SOAP API.

Service Endpoints

ResourceURL
SOAP servicehttps://os.ecgrid.io/v4.1/prod/ECGridOS.asmx
WSDLhttps://os.ecgrid.io/v4.1/prod/ECGridOS.asmx?WSDL
Service namespacehttp://www.ecgridos.net/

Option 1 — Manual HttpClient

Use a raw HttpClient to POST SOAP envelopes when you need minimal dependencies and full control over the wire format. This is the approach used in the ECGrid-SOAP-dotnet10-Console-HttpClient sample.

SOAP envelope structure

Every ECGridOS request uses the same SOAP 1.1 envelope structure:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ecg="http://www.ecgridos.net/">
<soap:Body>
<ecg:MethodName>
<ecg:SessionID>your-session-id</ecg:SessionID>
<ecg:Param1>value1</ecg:Param1>
</ecg:MethodName>
</soap:Body>
</soap:Envelope>

SOAPAction header

Every request must include a SOAPAction header matching the method being called:

SOAPAction: "http://www.ecgridos.net/MethodName"

Complete C# example

// .NET 10 — manual HttpClient SOAP, minimal dependencies
// Uses IHttpClientFactory; never instantiate HttpClient directly in production

using System.Net.Http.Headers;
using System.Text;
using System.Xml.Linq;

/// <summary>Sends a raw SOAP request to the ECGridOS endpoint and returns the response XML.</summary>
static async Task<XDocument> SendSoapAsync(
IHttpClientFactory httpClientFactory,
string methodName,
string soapBody)
{
const string Endpoint = "https://os.ecgrid.io/v4.1/prod/ECGridOS.asmx";
const string Namespace = "http://www.ecgridos.net/";

var envelope = $"""
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ecg="{Namespace}">
<soap:Body>
{soapBody}
</soap:Body>
</soap:Envelope>
""";

using var content = new StringContent(envelope, Encoding.UTF8, "text/xml");
content.Headers.Add("SOAPAction", $"\"{Namespace}{methodName}\"");

var http = httpClientFactory.CreateClient("ECGridSOAP");
var response = await http.PostAsync(Endpoint, content);
response.EnsureSuccessStatusCode();

var xml = await response.Content.ReadAsStringAsync();
return XDocument.Parse(xml);
}

/// <summary>Logs in and returns a SessionID string.</summary>
static async Task<string> LoginAsync(IHttpClientFactory factory, string email, string password)
{
var body = $"""
<ecg:Login>
<ecg:Email>{email}</ecg:Email>
<ecg:Password>{password}</ecg:Password>
</ecg:Login>
""";

var doc = await SendSoapAsync(factory, "Login", body);

XNamespace ns = "http://www.ecgridos.net/";
var sessionID = doc.Descendants(ns + "LoginResult").FirstOrDefault()?.Value
?? throw new InvalidOperationException("Login failed — no SessionID returned.");

return sessionID;
}

dotnet-svcutil generates a strongly-typed C# proxy from the WSDL.

Install the tool

dotnet tool install --global dotnet-svcutil

Generate the proxy

Run this from your project directory:

dotnet-svcutil https://os.ecgrid.io/v4.1/prod/ECGridOS.asmx?WSDL --outputDir ./ServiceReference --namespace ECGrid.Soap.Client

This creates:

  • ServiceReference/Reference.cs — the generated proxy class
  • ServiceReference/dotnet-svcutil.params.json — the generation parameters (commit this file)

Add the required NuGet package

dotnet add package System.ServiceModel.Http

Use the generated proxy

// .NET 10 — dotnet-svcutil generated proxy
using ECGrid.Soap.Client;
using Microsoft.Extensions.Configuration;

var config = new ConfigurationBuilder()
.AddEnvironmentVariables()
.AddJsonFile("appsettings.json", optional: true)
.Build();

var email = config["ECGrid:Email"] ?? throw new InvalidOperationException("ECGrid:Email is not configured.");
var password = config["ECGrid:Password"] ?? throw new InvalidOperationException("ECGrid:Password is not configured.");

// Create the client — endpoint is defined in the generated binding
using var client = new ECGridOSPortTypeClient(
ECGridOSPortTypeClient.EndpointConfiguration.ECGridOSPort);

var sessionID = string.Empty;
try
{
sessionID = await client.LoginAsync(email, password);
Console.WriteLine($"Logged in. SessionID: {sessionID[..8]}...");

// All subsequent calls pass sessionID as the first argument
var mailboxInfo = await client.MailboxInfoAsync(sessionID, mailboxID: 0);
Console.WriteLine($"Default mailbox: {mailboxInfo.MailboxName}");
}
finally
{
if (!string.IsNullOrEmpty(sessionID))
await client.LogoutAsync(sessionID);
}

Option 3 — CoreWCF

CoreWCF is the right choice when you are migrating existing WCF client code to .NET 10. It provides a familiar ChannelFactory<T> programming model.

Add the NuGet package

dotnet add package CoreWCF.Http

Configure the channel

// .NET 10 — CoreWCF ChannelFactory, mirrors classic WCF client usage
using CoreWCF;
using CoreWCF.Channels;
using ECGrid.Soap.Contracts; // your manually-defined or generated service contract

var binding = new BasicHttpsBinding();
var endpoint = new EndpointAddress("https://os.ecgrid.io/v4.1/prod/ECGridOS.asmx");

using var factory = new ChannelFactory<IECGridOS>(binding, endpoint);
var channel = factory.CreateChannel();

var sessionID = await channel.LoginAsync(email, password);
try
{
var parcelList = await channel.ParcelInBoxAsync(sessionID, mailboxID, beginDate, endDate);
}
finally
{
await channel.LogoutAsync(sessionID);
factory.Close();
}
note

CoreWCF is best suited for migrating existing WCF code. For greenfield projects, use dotnet-svcutil (Option 1) or manual HttpClient (Option 3).


Choosing Between the Three Options

ScenarioRecommended option
New .NET 10 project, SOAP requireddotnet-svcutil
Migrating existing WCF client codeCoreWCF
Minimal dependencies, full wire controlManual HttpClient