Saltar al contenido

Cómo obtener las cadenas de archivos .resx en el núcleo de asp.net

Te doy la bienvenida a nuestra página web, aquí vas a encontrar la resolución que estás buscando.

Solución:

.NET Core cambió la forma en que funcionan los archivos de recursos de una manera que creo que es deficiente y confusa (me tomó días averiguarlo), pero esto es lo que debe hacer:

  1. Agregue el siguiente código a Startup.cs – Nota: Cambie los idiomas que admite y el ResourcePath de “Recursos” será solo la carpeta en la que almacenará los archivos .resx más adelante.

Como dijo JustAMartin en los comentarios: si planea poner su SharedResource archivo dentro Recursos carpeta y configure su espacio de nombres para que termine con Recursos, luego no configure o.ResourcesPath = "Resources" Solo usa services.AddLocalization(), de lo contrario, comenzará a buscar en la carpeta Resources.Resources, que no existe.

        services.AddLocalization(o => o.ResourcesPath = "Resources");
        services.Configure(options =>
        
            var supportedCultures = new[]
            
                new CultureInfo("en-US"),
                new CultureInfo("en-GB"),
                new CultureInfo("de-DE")
            ;
            options.DefaultRequestCulture = new RequestCulture("en-US", "en-US");

            // You must explicitly state which cultures your application supports.
            // These are the cultures the app supports for formatting 
            // numbers, dates, etc.

            options.SupportedCultures = supportedCultures;

            // These are the cultures the app supports for UI strings, 
            // i.e. we have localized resources for.

            options.SupportedUICultures = supportedCultures;
        );
  1. Cree una carpeta en cualquier proyecto en el que desee almacenar los archivos resx; por defecto, llámelo “Recursos”.

  2. Cree un nuevo archivo resx con la cultura específica y el nombre del archivo que buscará más adelante: si tuviera uno compartido, podría hacerlo: SharedResource.en-US.resx. Luego, desactive la generación automática de código, ya que ahora es inútil.

  3. Cree una clase llamada “SharedResource” en la misma ubicación que su archivo resx. Puede estar en blanco, solo debe estar allí para que pueda consultarlo más tarde.

  4. Donde quiera que desee utilizar su recurso, IoC inyecte (en este ejemplo) IStringLocalizer< SharedResource > con el nombre “_localizer” o algo así.

  5. Finalmente, puede hacer referencia a una entrada en el archivo de recursos haciendo _localizer[“My_Resource_Name”]

  6. Agregue otro idioma creando un nuevo archivo resx llamado “SharedResource.de-DE.resx” o lo que sea, en esa misma carpeta.

La carpeta “Recurso” se utilizará en todos los ensamblajes para buscarlos todos. Por lo tanto, esta carpeta podría terminar bastante desordenada, especialmente si comienza a ver cosas específicas aquí.

Veo lo que los desarrolladores estaban tratando de hacer aquí, pero renunciaron demasiado para llegar allí. La gente puede codificar y agregar material de traducción sin tener que traducir nada. Facilitaron que los desarrolladores tuvieran la traducción en mente desde el principio, pero terminan haciendo que sea mucho más trabajo para los desarrolladores que realmente usan traducciones. Ahora no podemos generar nada automáticamente. Tenemos que IoC inyectar una referencia a las traducciones para poder acceder a ellas (no más static a menos que desee utilizar el antipatrón ServiceLocater). Todos los nombres son cadenas codificadas de forma rígida, por lo que ahora, si escribe mal una traducción, simplemente devolverá el string lo diste, frustrando el propósito de tener una traducción en primer lugar, lo que significa que probablemente necesitará una envoltura alrededor de esto para no depender de constantes en todas partes.

No puedo creer que alguien pensara que esto era una buena idea, para ser honesto. De todos modos, ¿por qué hacer todo lo posible por los desarrolladores que no se preocupan por las traducciones?

Terminé creando un envoltorio alrededor de este estilo. Lo único bueno de esto es que si decide que desea obtener recursos de la base de datos, no será necesario ningún cambio de código anterior, pero ahora debe agregar la entrada de recursos, agregarla a la interfaz y luego implementarla para extraer volver a salir. Usé nameof (), así que no necesitaba usar constantes, pero esto sigue siendo frágil, ya que si el nombre de la propiedad o el nombre del archivo resx cambia, romperá la traducción sin ningún tipo de falla; probablemente necesitaré una prueba de integración para asegurarme de que no obtengo el mismo valor que envío:

public interface ICommonResource

    string ErrorUnexpectedNumberOfRowsSaved  get; 
    string ErrorNoRecordsSaved  get; 
    string ErrorConcurrency  get; 
    string ErrorGeneric  get; 

    string RuleAlreadyInUse  get; 
    string RuleDoesNotExist  get; 
    string RuleInvalid  get; 
    string RuleMaxLength  get; 
    string RuleRequired  get; 


public class CommonResource : ICommonResource

    private readonly IStringLocalizer _localizer;

    public CommonResource(IStringLocalizer localizer) =>
        _localizer = localizer;

    public string ErrorUnexpectedNumberOfRowsSaved => GetString(nameof(ErrorUnexpectedNumberOfRowsSaved));
    public string ErrorNoRecordsSaved => GetString(nameof(ErrorNoRecordsSaved));
    public string ErrorConcurrency => GetString(nameof(ErrorConcurrency));
    public string ErrorGeneric => GetString(nameof(ErrorGeneric));

    public string RuleAlreadyInUse => GetString(nameof(RuleAlreadyInUse));
    public string RuleDoesNotExist => GetString(nameof(RuleDoesNotExist));
    public string RuleInvalid => GetString(nameof(RuleInvalid));
    public string RuleMaxLength => GetString(nameof(RuleMaxLength));
    public string RuleRequired => GetString(nameof(RuleRequired));

    private string GetString(string name) =>
        _localizer[name];

La versión antigua (como en asp.net) es crear un archivo de recursos predeterminado como MyResources.resx y otros archivos para diferentes culturas MyResources.fr.resx, … y recuperar los valores con MyResources.MyValue1. La creación de MyResources.resx generará un archivo .cs con todos los valores de sus recursos como static propiedades.

.Net Core recomienda trabajar con IStringLocalizer donde T es una clase creada por usted que coincide con el nombre de sus archivos de recursos. Puede comenzar el desarrollo sin ningún archivo de recursos y agregarlos más tarde. Tienes que inyectar (IStringLocalizer< MyResources > localizador) en su controlador y luego obtenga el valor con _localizer[“MyValue1”];

Puede echar un vistazo a la documentación oficial principal de .net aquí

Para un reemplazo más directo, he creado ResXResourceReader.NetStandard, que vuelve a empaquetar ResXResourceReader y ResXResourceWriter para .NET Standard (que también significa .NET Core).

Te mostramos comentarios y calificaciones

Te invitamos a reafirmar nuestra faena ejecutando un comentario y puntuándolo te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *