Unifying .NET AI Clients with a Single Azure AI Foundry Resource
Unifying .NET AI Clients with a Single Azure AI Foundry Resource
Date: 2026-08-15
How to consolidate Azure AI Language and Translator clients into one Azure AI Foundry resource endpoint—solving SDK routing quirks for seamless multi-service AI integration.
Tags: ["Azure", "AI Foundry", "DotNet", "Azure SDK", "Text Analytics", "Translation"]
In modern cloud-native applications, managing multiple AI services across distinct Azure resources can quickly become cumbersome. Many .NET developers using Azure AI's Text Analytics and Translation services often face the challenge of maintaining separate endpoints and credentials, increasing complexity in configuration and deployment.
Azure AI Foundry bundles multiple cognitive services—Language, Translator, Speech, Vision—into a single multi-service resource. This approach simplifies client initialization and resource management by providing one endpoint and a common set of credentials.
This post explains how to migrate .NET clients from separate Azure AI Language and Azure AI Translator resources onto a single Azure AI Foundry resource. We highlight an important SDK behavior that affects the translation client’s routing and walk through a practical fix. You will learn how to unify your AI clients under one resource with minimal code changes, improving maintainability.
Architecture Overview
┌─────────────────────────────────────────────┐
│ Azure AI Foundry │
├─────────────────────────────────────────────┤
│ • Multi-service AI Resource │
│ • Supports Language, Translator, Speech, │
│ Vision, and more │
│ • Single Endpoint and Credential Management │
└─────────────────────────────────────────────┘
↓ ↓
┌─────────────────────────┐ ┌─────────────────────────┐
│ TextAnalyticsClient │ │ TextTranslationClient │
│ (Language Service) │ │ (Translator Service) │
└─────────────────────────┘ └─────────────────────────┘
↓ ↓
Unified AI-powered .NET Application
Key Technical Observations
-
Multi-Service Azure AI Foundry Resource — Combines multiple AI services into a single resource endpoint (
*.services.ai.azure.com), enabling streamlined authentication and configuration. -
SDK Endpoint Hostname Detection Logic — The Azure.AI.Translation.Text SDK infers API routing based on whether the endpoint hostname contains the substring "cognitiveservices". This determines if the
/translator/textpath prefix is added. -
Routing Prefix Breaks with Foundry Endpoint — Since the Foundry endpoint hostname uses
*.services.ai.azure.com(not containing "cognitiveservices"), the Translation SDK omits the routing prefix and calls an incorrect API path, causing 404 errors. -
Manual URI Prefixing as Workaround — Explicitly appending
/translator/textto the Foundry endpoint URI forces correct routing, restoring Translation client functionality without modifying SDK internals. -
Safe SDK Future Compatibility — The prefixed URI is absolute-rooted, so even if future SDK versions add the prefix automatically for Foundry hosts, it won’t cause double prefixing or broken URLs.
-
Credential Reuse with DefaultAzureCredential — Utilizing Azure.Identity's
DefaultAzureCredentialsimplifies authentication across multiple services under the Foundry resource.
How It Works
1. Legacy Setup: Separate Endpoints for Text Analytics and Translation
.NET applications typically instantiate:
var languageEndpoint = "https://lang-demo-service-001.cognitiveservices.azure.com";
var translatorEndpoint = "https://trsl-demo-service-001.cognitiveservices.azure.com";
var credentials = new DefaultAzureCredential();
// Text Analytics Client
var textAnalyticsClient = new TextAnalyticsClient(new Uri(languageEndpoint), credentials);
var detectedLanguage = await textAnalyticsClient.DetectLanguageAsync("Hello");
// Translation Client
var textTranslationClient = new TextTranslationClient(credentials, new Uri(translatorEndpoint));
var translateResponse = await textTranslationClient.TranslateAsync("fr", "Hello", "en");
These clients communicate with distinct service endpoints, each managing their own keys and authentication.
2. Moving to Azure AI Foundry Single Endpoint
Azure AI Foundry exposes a unified endpoint like:
var apiEndpoint = "https://aif-demo-service-001.services.ai.azure.com";
var credentials = new DefaultAzureCredential();
var textAnalyticsClient = new TextAnalyticsClient(new Uri(apiEndpoint), credentials);
var textTranslationClient = new TextTranslationClient(credentials, new Uri(apiEndpoint));
This lets developers configure one endpoint and credential for all AI services.
3. The Problem: Translation Client 404 Error
When the TextTranslationClient targets the Foundry endpoint without the routing prefix, it sends requests to /translate instead of /translator/text/translate returning a 404 Not Found error.
This happens because the SDK checks if the endpoint host contains "cognitiveservices" to decide whether to prepend /translator/text:
private const string PLATFORM_HOST = "cognitiveservices";
internal static bool IsPlatformHost(this Uri uri) =>
uri.Host?.Contains(PLATFORM_HOST) == true;
private const string PLATFORM_PATH = "/translator/text";
if (endpoint.IsPlatformHost())
{
this._endpoint = new Uri(endpoint, PLATFORM_PATH);
}
Since the Foundry endpoint hostname lacks "cognitiveservices", the prefix is skipped.
4. The Fix: Manually Add the Routing Prefix
Passing the prefix explicitly when constructing the TextTranslationClient restores correct routing:
var apiEndpoint = "https://aif-demo-service-001.services.ai.azure.com";
var credentials = new DefaultAzureCredential();
var textTranslationClient = new TextTranslationClient(
credentials,
new Uri($"{apiEndpoint}/translator/text"));
var translateResponse = await textTranslationClient.TranslateAsync("fr", "Hello", "en");
var translatedText = translateResponse.Value.FirstOrDefault()?.Translations.FirstOrDefault()?.Text;
Console.WriteLine(translatedText); // Outputs: Bonjour
This bypasses the SDK’s hostname check and properly targets the translation API on the Foundry resource.
5. Verifying Future SDK Compatibility
Because .NET’s new Uri(base, relative) replaces rather than appends the path if the relative is absolute-rooted, any future SDK change adding the prefix for Foundry hosts will not cause duplication:
Uri uri = new Uri(new Uri("https://aif-demo-service-001.services.ai.azure.com/translator/text"), "/translator/text");
Console.WriteLine(uri.ToString()); // Outputs the same single prefixed URI
This ensures robustness of the workaround.
Quick Tips & Tricks
-
Use DefaultAzureCredential for Simplicity
LeverageDefaultAzureCredentialto authenticate against Azure AI Foundry without managing explicit keys or tokens. -
Always Validate SDK Endpoint Routing Logic
When migrating to unified multi-service endpoints, verify how SDKs derive request paths from hostnames to avoid silent failures like 404 errors. -
Manually Adjust Endpoint URIs When Needed
If an SDK assumes certain host patterns to build API routes, explicitly set the URI to include necessary path prefixes. -
Monitor SDK GitHub Issues and Updates
Keep track of SDK repository issues for fixes or improvements related to multi-service endpoint support. -
Test Raw REST Calls to Isolate SDK vs Service Issues
Use tools like curl or Postman to verify if the service endpoint works independently of the SDK. -
Plan for Resource Consolidation Early
Adopting multi-service resources like Azure AI Foundry early simplifies resource management.
Conclusion
Migrating your .NET AI clients to a single Azure AI Foundry resource streamlines application configuration and reduces resource sprawl. While the Azure SDKs provide strong integration, subtle hostname-based routing logic can lead to unexpected failures in multi-service scenarios. Understanding the SDK’s internal routing behavior and applying targeted URI prefix fixes can save debugging time and enable smooth multi-service usage from a unified endpoint.
Applying manual URI adjustments is a practical, forward-compatible approach that unifies your Text Analytics and Translation clients effortlessly. This simplification helps developers build AI-powered .NET applications with less maintenance overhead.
References
- Original Blog Post by Jaliya Udagedara — Detailed walkthrough and code samples.
Author: Jaliya Udagedara