Skip to main content

SOAP SvcUtil Sample

The ECGrid-SOAP-dotnet10-Console-SvcUtil project demonstrates calling the ECGridOS SOAP API using a typed client proxy generated by dotnet-svcutil. The generated proxy provides strongly typed method signatures and response objects, eliminating manual XML construction.

:::caution Established API The ECGridOS SOAP API is in maintenance mode. For new integrations, use the REST API instead. This sample is provided for teams maintaining or migrating existing SOAP-based integrations. :::

Project Location

samples/soap/ECGrid-SOAP-dotnet10-Console-SvcUtil/

What It Demonstrates

  • Generating a typed WCF-compatible proxy from the ECGridOS WSDL using dotnet-svcutil
  • Calling SOAP methods as strongly typed async methods
  • Session lifecycle: LoginAsync → operations → LogoutAsync
  • Operations covered: LoginAsync, ParcelInBoxAsync, ParcelDownloadAsync, ParcelDownloadConfirmAsync, LogoutAsync

Key Files

FilePurpose
Program.csEntry point — full session workflow using the generated proxy
Reference/Generated proxy code produced by dotnet-svcutil (do not edit manually)
appsettings.jsonLogin credentials

Regenerating the Proxy

The generated proxy in Reference/ was created from the ECGridOS WSDL. If the WSDL changes, regenerate it with:

# Install the tool globally (one-time)
dotnet tool install -g dotnet-svcutil

# Regenerate from the live WSDL — run from the project directory
dotnet-svcutil https://os.ecgrid.io/v4.1/prod/ECGridOS.asmx?WSDL --outputDir Reference

This produces a Reference.cs file and updates the project's NuGet references for System.ServiceModel.

note

Commit the generated Reference/ files to source control so that other developers can build without running dotnet-svcutil. Regenerate only when the WSDL changes.

Key Patterns

Client Instantiation

// The generated proxy class is typically named ECGridOSSoapClient
// Endpoint address matches the live ECGridOS service
var binding = new BasicHttpsBinding();
var endpoint = new EndpointAddress("https://os.ecgrid.io/v4.1/prod/ECGridOS.asmx");

await using var client = new ECGridOSSoapClient(binding, endpoint);

Session Lifecycle

// Program.cs — .NET 10 top-level statements

// Load credentials from IConfiguration — never hardcoded
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.AddUserSecrets<Program>()
.Build();

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

await using var client = new ECGridOSSoapClient(binding, endpoint);

// --- Login ---
// LoginAsync returns a typed SessionInfo object; the SessionID is used for all subsequent calls
var loginResult = await client.LoginAsync(
config["ECGridOS:Login"]!,
config["ECGridOS:Password"]!);

var sessionId = loginResult.SessionID;

// --- Check inbox ---
var inboxResult = await client.ParcelInBoxAsync(
sessionId,
int.Parse(config["ECGridOS:MailboxId"]!));

// ParcelInBoxAsync returns an array of ParcelIDInfo objects
foreach (var parcel in inboxResult ?? [])
{
// --- Download parcel ---
// ParcelDownloadAsync returns the EDI file content as a base64-encoded byte array
var downloadResult = await client.ParcelDownloadAsync(sessionId, parcel.ParcelID);

if (downloadResult?.Content is { Length: > 0 } content)
{
await File.WriteAllBytesAsync($"parcel-{parcel.ParcelID}.edi", content);

// --- Confirm download ---
// Must be called to mark the parcel as delivered in ECGrid
await client.ParcelDownloadConfirmAsync(sessionId, parcel.ParcelID);

Console.WriteLine($"Parcel {parcel.ParcelID} downloaded and confirmed.");
}
}

// --- Logout ---
// Always logout to release the session on the server
await client.LogoutAsync(sessionId);
Console.WriteLine("Done.");

Error Handling

// Wrap SOAP calls in try/catch for FaultException to handle SOAP faults gracefully
try
{
var result = await client.ParcelDownloadAsync(sessionId, parcelId);
}
catch (FaultException<ECGridOSFault> fault)
{
// ECGridOS-specific error details are in the fault detail
Console.Error.WriteLine($"ECGridOS error {fault.Detail.ErrorCode}: {fault.Detail.ErrorString}");
}
catch (CommunicationException ex)
{
// Network or channel errors
Console.Error.WriteLine($"Communication error: {ex.Message}");
}

Configuration

{
"ECGridOS": {
"Login": "",
"Password": "",
"MailboxId": 0
}
}

Store credentials with user-secrets:

cd samples/soap/ECGrid-SOAP-dotnet10-Console-SvcUtil
dotnet user-secrets set "ECGridOS:Login" "your-login"
dotnet user-secrets set "ECGridOS:Password" "your-password"

How to Run

cd samples/soap/ECGrid-SOAP-dotnet10-Console-SvcUtil
dotnet user-secrets set "ECGridOS:Login" "your-login"
dotnet user-secrets set "ECGridOS:Password" "your-password"
dotnet run

Comparison with the HttpClient Sample

AspectSvcUtil ProxyHttpClient Manual
Setup effortGenerate proxy onceWrite envelope helpers manually
Type safetyFull — compiler checks method signaturesNone — all XML strings
DependenciesSystem.ServiceModel.Http NuGetNo extra packages
MaintenanceRegenerate when WSDL changesUpdate XML strings manually
Best forLonger-lived integrationsMinimal-dependency or scripted use

See SOAP HttpClient Sample for the manual approach.

See Also