# General Translation Knowledge Base: ¿Cómo traduzco archivos .resx en una aplicación .NET?
URL: https://generaltranslation.com/es/kb/translate-resx-files.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Crea una copia de cada archivo .resx neutro con la referencia cultural en el nombre, como Resources.fr.resx, y traduce solo el valor de cada entrada, sin modificar los nombres, los comentarios ni los marcadores de posición como {0}. .NET compila cada referencia cultural en un ensamblado satélite y, si falta algo, recurre de fr-CA a fr y, por último, al archivo neutro. La CLI de General Translation genera esos archivos por referencia cultural a partir del archivo de origen neutro.
Category: Traducción
Last updated: 2026-10-28
Authors: General Translation Team
Published: 2026-10-28

Un archivo .resx es una lista XML de recursos con nombre. El archivo neutro, como `Resources.resx`, contiene tu idioma predeterminado, y cada traducción es un archivo ubicado junto a él con la referencia cultural en el nombre, como `Resources.fr.resx`, que contiene los mismos nombres con los valores traducidos. En tiempo de ejecución, `ResourceManager` elige el archivo que corresponde a la referencia cultural actual de la UI y, para cualquier recurso que falte, recurre a las referencias culturales primarias.

## Qué contiene un archivo .resx

Cada recurso es un elemento `<data>`. Su atributo `name` es la clave que busca tu código, `<value>` contiene el texto y un `<comment>` opcional le indica al traductor para qué sirve el texto. Aquí tienes un fragmento (un archivo real también comienza con un bloque de esquema y con entradas `<resheader>` que Visual Studio genera automáticamente):

```xml title="Resources/SharedResource.resx"
<data name="Checkout" xml:space="preserve">
  <value>Checkout</value>
  <comment>Button that starts payment for the items in the cart.</comment>
</data>
<data name="ItemsInCart" xml:space="preserve">
  <value>You have {0} items in your cart.</value>
  <comment>{0} is the number of items.</comment>
</data>
```

El archivo en francés tiene los mismos atributos `name`, pero con valores en francés. Solo cambian los valores de las cadenas. Los nombres funcionan como claves de búsqueda, y los recursos que no son cadenas, como las imágenes (que llevan un atributo `type` y, a menudo, un atributo `mimetype`), normalmente se dejan tal cual. Microsoft recomienda editar los archivos .resx en Visual Studio y no a mano, porque el XML debe seguir estando bien formado y respetar su formato predefinido ([Microsoft: Create resource files](https://learn.microsoft.com/en-us/dotnet/core/extensions/create-resource-files)).

## Cómo encuentra .NET la traducción correcta

Asigna a cada traducción el mismo nombre raíz que el archivo neutro, con la referencia cultural antes de la extensión: `Resources.fr.resx`, `Resources.fr-CA.resx`. Al compilar, los recursos neutros se incrustan en el ensamblado principal y cada referencia cultural se compila en un ensamblado satélite dentro de una carpeta con el nombre de esa referencia cultural, como `fr/MyApp.resources.dll`.

Cuando la aplicación solicita una cadena, .NET la busca en el ensamblado satélite de la referencia cultural solicitada, luego en el de su referencia cultural primaria, y así sucesivamente, hasta recurrir a los recursos neutros. Para una solicitud `fr-CA`, el orden es `fr-CA`, luego `fr` y, por último, el archivo neutro. Si no existe ningún archivo de recursos ni siquiera para la referencia cultural predeterminada, lanza `MissingManifestResourceException` o `MissingSatelliteAssemblyException`. En Linux y macOS, el nombre de la carpeta de la referencia cultural debe coincidir exactamente con `CultureInfo.Name`, incluidas mayúsculas y minúsculas ([Microsoft: Empaquetar e implementar recursos](https://learn.microsoft.com/en-us/dotnet/core/extensions/package-and-deploy-resources)).

El mecanismo de reserva te permite traducir una sola vez para toda una familia de regiones. Microsoft sugiere un único archivo `de` para los usuarios de `de-DE`, `de-AT` y `de-CH`, con archivos regionales que contengan solo las cadenas que difieren. Pero también significa que una traducción que falte nunca lanza una excepción: el usuario ve el idioma neutro y nada en la compilación te avisa. (Consulta [¿Qué son los códigos de configuración regional?](/kb/locale-codes)).

## Usar .resx en ASP.NET Core, Windows Forms y WPF

### ASP.NET Core

Registra los servicios de localización, elige las referencias culturales que admites y agrega el middleware ([Microsoft: Select language and culture](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/select-language-culture)):

```csharp title="Program.cs"
builder.Services.AddLocalization(options => options.ResourcesPath = "Resources");

builder.Services.Configure<RequestLocalizationOptions>(options =>
{
    var supportedCultures = new[] { "en-US", "fr" };
    options.SetDefaultCulture(supportedCultures[0])
        .AddSupportedCultures(supportedCultures)
        .AddSupportedUICultures(supportedCultures);
});

var app = builder.Build();

// Determina la referencia cultural a partir de la cadena de consulta, una cookie o Accept-Language, en ese orden.
app.UseRequestLocalization();
```

Después, inyecta `IStringLocalizer<T>` y busca las cadenas por nombre, pasando a continuación los argumentos de formato: `localizer["ItemsInCart", count]`. Los archivos de recursos se nombran según el nombre de tipo completo de la clase sin el nombre del ensamblado, de modo que `Controllers.HomeController` lee `Controllers.HomeController.fr.resx` en la carpeta `Resources` (o `HomeController.fr.resx` en `Resources/Controllers`), y una clase marcadora vacía `SharedResource` agrupa las cadenas compartidas por toda la aplicación. `SupportedUICultures` determina qué archivos .resx se leen; `SupportedCultures` determina el formato de fechas y números ([Microsoft: Provide localized resources](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/provide-resources)).

`IStringLocalizer` devuelve la propia clave cuando no existe ninguna traducción, por lo que Microsoft documenta un flujo de trabajo sin ningún .resx neutro: `localizer["About Title"]` muestra &quot;About Title&quot; en inglés ([Microsoft: Make content localizable](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/localization/make-content-localizable)). Esto sirve para mostrar el texto, pero no deja ningún archivo de origen que un traductor o una herramienta puedan leer. Si quieres generar traducciones a partir de un archivo, usa claves con nombre y un .resx neutro cuyos valores sean el texto en inglés, el enfoque tradicional que Microsoft también documenta.

### Windows Forms y WPF

En Windows Forms, establece la propiedad **Localizable** de un formulario en `true` y, a continuación, elige una referencia cultural en su propiedad **Language**; al modificar el texto en el diseñador, Visual Studio lo guarda en un archivo específico de esa referencia cultural, como `Form1.es-ES.resx` ([Microsoft: Localizing a hybrid application](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/walkthrough-localizing-a-hybrid-application)). Los archivos generados por el diseñador también contienen entradas que no son texto, como los nombres que empiezan por `>>`. Las aplicaciones WPF pueden cargar cadenas de archivos .resx mediante `ResourceManager`; el tutorial de Microsoft sobre localización de XAML utiliza la herramienta LocBaml, que el propio tutorial describe como un ejemplo que «no es una aplicación lista para producción» ([Microsoft: Localize a WPF app](https://learn.microsoft.com/en-us/dotnet/desktop/wpf/advanced/how-to-localize-an-application)).

### Edítalos en Visual Studio

Desde la versión 17.11 de Visual Studio 2022, el Resource Explorer muestra cada archivo .resx con sus referencias culturales una al lado de otra. Haz clic con el botón derecho en un archivo .resx y elige **Open With &gt; Resource Explorer** (o pulsa **Ctrl+Alt+R**). Te avisa cuando falta una traducción (&quot;No value&quot;) y cuando los marcadores de posición no coinciden con los de la referencia cultural neutra; por ejemplo, `Hello, {name}!` frente a `Hola, {nombre}!` ([Microsoft: Manage application resources](https://learn.microsoft.com/en-us/visualstudio/ide/managing-application-resources-dotnet)).

## Qué falla al traducir archivos .resx

* **Marcadores de posición.** Los elementos de formato compuesto de .NET tienen la forma `{index[,width][:formatString]}`, como `{0}`, `{1,-10}` o `{0:N2}`. Una traducción puede reordenarlos o usar uno dos veces, pero un elemento de formato que hace referencia a un argumento inexistente lanza `FormatException` en tiempo de ejecución, y si se omite uno, el valor se pierde sin ningún aviso. Las llaves literales se escriben `{{` y `}}` ([Microsoft: Formato compuesto](https://learn.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting)).
* **Nombres.** Si se traduce un atributo `name`, la búsqueda no encuentra nada y esa cadena se muestra en el idioma neutro.
* **XML.** Un valor que contenga `&` o `<` debe mantenerse escapado como `&amp;` y `&lt;`; de lo contrario, el archivo no compilará.
* **Teclas de acceso.** En Windows Forms, `&File` subraya la F. La traducción debe incluir exactamente un `&` delante de una letra adecuada.
* **Comentarios.** Los comentarios son contexto para los traductores, no texto que haya que traducir. La guía de Windows App SDK de Microsoft indica que los traductores no necesitan traducirlos ([Microsoft: Localizar cadenas](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/mrtcore/localize-strings)).
* **Desincronización.** Cuando un desarrollador añade un nombre al archivo neutro, también hay que añadirlo a todos los archivos de referencia cultural. El mecanismo de reserva oculta la omisión, así que comprueba si faltan valores antes de cada lanzamiento.

## Formas de traducir archivos .resx

| Enfoque                                                           | Conserva nombres y recursos que no son cadenas                                                              | Comprobación de marcadores de posición                                                                                  | Mantener las referencias culturales sincronizadas                                                                                                          | Recomendado cuando                                                              |
| ----------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| Resource Explorer de Visual Studio, a mano                        | Sí                                                                                                          | Avisa de las discrepancias                                                                                              | Muestra los valores que faltan en cada referencia cultural                                                                                               | Uno o dos idiomas que habla alguien del equipo                                  |
| Traductores o un sistema de gestión de traducciones (TMS)         | Sí, si el TMS analiza .resx                                                                                 | Depende de su control de calidad                                                                                        | Mediante la sincronización del repositorio del TMS                                                                                           | Traductores profesionales o un proveedor se encargan del trabajo                |
| Un script que llame a una API de traducción automática o a un LLM | Solo si tu script analiza el XML y envía los valores                                                        | Las escribes tú                                                                                                         | Vuelves a ejecutarlo y haces un diff                                                                                                         | Te encargarás de mantener el script y su validación                             |
| Pegar el archivo en un asistente de chat                          | Nada lo garantiza                                                                                           | Ninguna                                                                                                                 | Manual                                                                                                                                       | Un archivo puntual que revisarás línea por línea                                |
| CLI de General Translation                                        | Traduce solo los valores de cadena; conserva los nombres, los comentarios y los recursos que no son cadenas | Si una traducción modifica u omite un marcador de posición, se descarta y .NET usa el valor de reserva para esa entrada | Reutiliza las traducciones de las entradas sin cambios; ejecuta [`gt translate`](/docs/cli/reference/commands/translate) en cada lanzamiento | Los archivos de recursos están en el repositorio y cambian con cada lanzamiento |

Usa Resource Explorer para uno o dos idiomas que un compañero pueda revisar. Usa un [TMS](/kb/what-is-a-translation-management-system) cuando los traductores profesionales trabajen fuera de la base de código. Elige General Translation cuando los archivos .resx cambien con cada lanzamiento y los archivos traducidos deban confirmarse junto con el código. (Consulta [General Translation frente a un TMS](/kb/general-translation-vs-tms)).

## Cómo traducir archivos .resx con General Translation

La CLI de General Translation, `gt`, traduce archivos .resx, así como archivos `.resw` con el mismo esquema, mediante la clave de archivo `resx` (`gt` 2.23.1 o posterior). El archivo neutro no lleva ninguna referencia cultural en su nombre, así que haz que `include` apunte a él, excluye los archivos traducidos que lo acompañan y usa `transform` para añadir la referencia cultural antes de la extensión:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["fr", "es-MX"],
  "files": {
    "resx": {
      "include": ["Resources/*.resx"],
      "exclude": ["Resources/*.[locales].resx"],
      "transform": {
        "match": "\\.resx$",
        "replace": ".{locale}.resx"
      }
    }
  }
}
```

En la carpeta `Resources`, esta configuración lee `Controllers.HomeController.resx` y escribe `Controllers.HomeController.fr.resx` y `Controllers.HomeController.es-MX.resx`, conservando intactos los nombres con puntos de ASP.NET Core. Incluya en `locales` todas las referencias culturales que ya distribuye: la exclusión `[locales]` omite los archivos traducidos solo de las configuraciones regionales definidas, por lo que un `Resources.de.resx` que no figure en la lista se leería como archivo de origen. En los proyectos UWP y WinUI que guardan los archivos `.resw` en una carpeta por idioma, use `"include": ["Strings/[locale]/Resources.resw"]` sin `transform`.

La CLI se ejecuta en Node.js 20 o posterior, incluso en un repositorio .NET; instálela como se indica en el [Inicio rápido de la CLI](/docs/cli/quickstart), inicie sesión con [`npx gt login`](/docs/cli/reference/commands/login) y configure `GT_PROJECT_ID` ([credenciales de la CLI](/docs/cli/guides/configuring#credentials)). Si su aplicación ya tiene traducciones, impórtelas primero con [`npx gt upload`](/docs/cli/reference/commands/upload). Después, ejecute [`npx gt translate`](/docs/cli/reference/commands/translate). En CI, guarde como `GT_API_KEY` una clave de API del proyecto con los permisos **Files &gt; Write** y **Translation queue &gt; Enabled**.

El archivo traducido es una copia del origen en la que solo se reemplazan los valores de cadena, por lo que los nombres, el orden de las entradas, el esquema y los bloques `<resheader>`, los comentarios y los recursos que no son cadenas quedan tal cual. Las entradas con un `mimetype`, un tipo distinto de `System.String`, un nombre de diseñador `>>` o un valor vacío no se envían a traducir. Cada `<comment>` se envía como contexto, y se respetan las instrucciones de localización de Microsoft que contenga, como `{Locked}`. Se conservan los marcadores de posición como `{0}`, `{0:N2}`, `{1,-10}`, `{count}` y las llaves dobles; una tecla de acceso `&` simple se mantiene delante de una letra adecuada, y el archivo descargado conserva la codificación y la marca de orden de bytes del origen. (Consulte la [referencia de .resx](/docs/cli/reference/formats/resx-files)).

Revise las traducciones en el [panel de control](/docs/platform/dashboard/guides/reviewing-translations) o en Visual Studio, y ejecute [`npx gt save-local`](/docs/cli/reference/commands/save-local) después de editar archivos localmente para que las ejecuciones posteriores conserven sus cambios. Un [grupo de contexto](/docs/platform/dashboard/guides/defining-context-for-translations) aplica a sus recursos .NET el mismo glosario y los mismos prompts personalizados que a los [archivos JSON](/kb/translate-json-files) de su aplicación web, de modo que un nombre de producto se traduce igual en ambos.

## Preguntas frecuentes

### ¿Cuál es la diferencia entre .resx y .resw?

Comparten el mismo esquema. Las aplicaciones UWP y WinUI usan archivos `.resw` organizados en una carpeta por idioma, como `Strings/en-US/Resources.resw` y `Strings/de-DE/Resources.resw`, en lugar de indicar la referencia cultural en el nombre del archivo ([Microsoft: Localize strings](https://learn.microsoft.com/en-us/windows/apps/windows-app-sdk/mrtcore/localize-strings)).

### ¿Necesito un archivo aparte para fr-CA si ya tengo fr?

No. Una solicitud de `fr-CA` recurre a `fr` para cualquier nombre que falte, así que solo necesitas añadir un archivo `fr-CA` con las cadenas que difieran.

### ¿Por qué mi aplicación ASP.NET Core sigue mostrándose en inglés después de agregar un archivo en francés?

Comprueba que `fr` esté incluido en `SupportedUICultures`, que el nombre del archivo coincida con el nombre del tipo de la clase y, en Linux o macOS, que la carpeta de la referencia cultural en el resultado de la compilación (por ejemplo, `fr`) coincida exactamente con `CultureInfo.Name`, respetando mayúsculas y minúsculas.

## Puntos clave

* Cada traducción es un archivo .resx paralelo con la referencia cultural en su nombre, como `Resources.fr.resx`; traduce los valores, nunca los atributos `name`.
* .NET recurre primero de `fr-CA` a `fr` y luego a los recursos neutros, así que, si falta una traducción, se muestra el idioma neutro en lugar de producirse un error.
* Un elemento de formato que hace referencia a un argumento inexistente lanza `FormatException`; revisa los marcadores de posición del tipo `{0}` en cada traducción.
* El Resource Explorer de Visual Studio 2022 17.11 detecta los valores que faltan y los marcadores de posición que no coinciden entre referencias culturales.
* La CLI de General Translation traduce archivos .resx y .resw con la clave `resx` (2.23.1+): conserva los nombres, los comentarios y los recursos que no son cadenas, y descarta cualquier traducción que rompa un marcador de posición.

## Related questions

- [¿Cómo traduzco archivos JSON de i18n?](https://generaltranslation.com/es/kb/translate-json-files.mdx): Traduce solo los valores de cadena de un archivo JSON de configuración regional. No modifiques las claves no plurales, los marcadores de posición como {{name}} ni las etiquetas, pero ten en cuenta que las claves plurales varían según el idioma: el polaco necesita inbox_few e inbox_many. Usa una herramienta o API que reconozca el formato y, después, analiza y valida el resultado antes de revisarlo.
- [¿Cómo traduzco archivos PO y POT?](https://generaltranslation.com/es/kb/translate-po-files.mdx): Rellena cada msgstr, incluidas todas las formas plurales que pide la cabecera Plural-Forms, y deja msgid, msgctxt y los marcadores de posición sin cambios. Ejecuta msgfmt --check para verificar las cabeceras, el número de formas plurales y los marcadores de posición en las entradas con una opción de formato, y comprueba por separado que ningún msgstr esté vacío. La CLI de General Translation genera un archivo PO traducido para cada idioma a partir de tu plantilla POT.
- [¿Qué es un sistema de gestión de traducciones (TMS)?](https://generaltranslation.com/es/kb/what-is-a-translation-management-system.mdx): Un sistema de gestión de traducciones (TMS) es un software que almacena tu contenido de origen y sus traducciones, y gestiona el flujo de trabajo de traducción: memoria de traducción, glosarios, revisión, traducción automática e integraciones. Su memoria de traducción reutiliza traducciones anteriores mediante coincidencias exactas o aproximadas. Crowdin, Lokalise, Phrase, Smartling y Transifex son ejemplos habituales.
- [General Translation frente a un TMS (Crowdin, Lokalise, Phrase)](https://generaltranslation.com/es/kb/general-translation-vs-tms.mdx): Elige General Translation cuando los desarrolladores quieran que la generación de traducciones, el contexto derivado del código y la revisión estén vinculados a los lanzamientos del producto. Conserva tus catálogos y tu biblioteca de renderizado actuales, o escribe JSX inline sin claves de traducción. Un TMS encaja con programas centrados en proveedores lingüísticos, editores CAT e intercambio de XLIFF; sus integraciones pueden automatizar las transferencias de archivos.
- [¿Cómo mantengo las traducciones actualizadas en cada despliegue?](https://generaltranslation.com/es/kb/translations-in-ci.mdx): Ejecuta la traducción como un paso del flujo antes de cada compilación de producción, para que el texto nuevo se publique ya traducido en el mismo despliegue que lo incorpora. La CLI gt de General Translation lo hace con npx gt translate, usando una clave de API del proyecto y el ID del proyecto almacenados como secretos de CI.

## Previous and next questions

- Previous question: [¿Cómo traduzco animaciones Lottie?](https://generaltranslation.com/es/kb/translate-lottie-animations.mdx)
- Next question: [¿Cómo traduzco archivos de configuración regional YAML?](https://generaltranslation.com/es/kb/translate-yaml-files.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/es/kb/sitemap.md) for every article.
