Frage

Ich möchte für ein ASP.NET-Projekt eine Zeichenfolge aus einem System.ComponentModel.DataAnnotations außer Kraft zu setzen. Muss ich Montage einen Satelliten machen, Messing mit Maßarbeit Aufgaben, al.exe usw.? Auch wenn ja, konnte ich nicht finden, wie .resx zu .resources wandeln es in al.exe zu füttern. Und wenn nicht, wo den .resx. setzen und wie man es nennen?

UPD: Um es klar: Ich habe eine benutzerdefinierte Ressource-Zeichenfolge anstelle eines von der Standard-Ressource aus der Baugruppe verwenden wollte. Ich wollte nicht, Änderungen der jedem Ort machen, dass Anwendungen diese Zeichenfolge. Schließlich gibt es die Ressourcen nur für sie zu überschreiben.

War es hilfreich?

Lösung 2

Während dieses seltsame ist, vor allem für die Menschen mit Open-Source-Lokalisierungstechnologien, man kann nicht eine Satelliteneinheit für jede Systemmontage bauen oder sogar eine 3rd-Party unterzeichnet ein:

  

Wenn Ihr Hauptbaugruppe verwendet starke   Namensgebung, Satelliten-Baugruppen müssen   mit dem gleichen privaten Schlüssel signiert als   die Hauptbaugruppe. wenn die   public / private Schlüsselpaar stimmt nicht überein   zwischen der Haupt und Satelliten   Baugruppen, Ihre Ressourcen nicht   geladen.

Ob das gleiche ist möglich, automatisch, aber ohne Satellitenassemblies, ist unbekannt, obwohl ich das bezweifeln.

Andere Tipps

Phil Haack hat einen hervorragenden Artikel Localizing ASP.Net MVC Validierung , die Sie gezielt führt durch die Saiten überschreiben. Dieser Artikel bezieht sich mehr auf DataAnnotations als es ASP.net MVC . So wird dies jedoch helfen, die Sie verwenden DataAnnotattions .

Im Folgenden habe ich die einfachsten Schritte aufgelistet Lokalisierte Ressourcen in Visual Studio hinzuzufügen.

  1. Öffnen Sie die Project Properties Dialog.
  2. Wählen Sie die Resources Tab.
  3. Klicken Sie auf ein neues default erstellen Ressourcen-Datei .
  4. Dadurch werden zwei Dateien in Ihrem Properties Ordner erstellen.
    • Resources.resx
    • Resources.Designer.cs
  5. Wenn Resources.resx hat geöffnet, ändern die es Access Modifier zu Public .
  6. Fügen Sie Ihre Saiten.

Um zusätzliche Ressourcendateien für spezifische Kulturen Sie werden müssen.

  1. Rechtsklick auf Ihre Project in der Solution Explorer .
  2. Wählen Sie Hinzufügen -> Neues Element -> Resource Datei.
  3. Name it Resources.en-us.resx . (Ersetzen Sie 'en-us' mit entsprechendem Code)
  4. Klicken Sie auf Hinzufügen
  5. Ziehen sie in den Properties Ordner.
  6. Öffnen Resources.en-US.resx und die ändern es Access Modifier zu Public .
  7. Fügen Sie Ihre Saiten.
  8. Wiederholen Sie für jede Kultur müssen Sie Unterstützung.

Während des Build-VS konvertiert die .resx Dateien .resource Dateien und Build-Wrapper-Klassen für Sie. Anschließend können Sie den Zugriff über den Namespace YourAssembly.Properties.Resources .

Mit dieser Anweisung using.

using YourAssembly.Properties;

Sie können mit Attributen wie diese dekorieren:

[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = "MyStringName")]

Hinweis: Früher habe ich die Eigenschaften Ordner für Konsistenz. So verwenden Sie die App_GlobalResources bewegen Sie die .resx Dateien gibt und ändern Sie Ihre Anweisung using den Verzeichnisnamen übereinstimmen. Wie folgt aus:

using YourAssembly.App_GlobalResources;

Edit: Das nächstgelegene, dass Sie zu stark typisierten Ressourcennamen zu bekommen wäre, so etwas zu tun:

public class ResourceNames
{
    public const string EmailRequired = "EmailRequired";
}

Sie können dann mit Attributen wie diese dekorieren.

[Required(ErrorMessageResourceType = typeof(Resources), ErrorMessageResourceName = ResourceNames.EmailRequired)]

So aktivieren Sie die automatische Client Kultur Erkennung der globalizationsection zur web.config Datei.

<configuration>
    <system.web>
        <globalization enableClientBasedCulture="true" culture="auto:en-us" uiCulture="auto:en-us"/>
    </system.web>
<configuration>

Hier habe ich eine Client-basierte Kultur aktiviert und stellen Sie die Kultur und Uiculture " Auto " mit einem Standardwert von „ en-us “.


Erstellen separate Satelliten-Baugruppen:

Die MSDN Erstellen von Satelliten-Baugruppen Artikel wird auch helfen. Wenn Sie die Satelliten-Baugruppen neu stellen Sie sicher, lesen Sie Verpackung und Bereitstellen von Ressourcen .

Wenn Satelliten-Baugruppen in der Vergangenheit zu schaffen, habe ich es für sinnvoll VS Build Ereignisse zu verwenden. Dies sind die Schritte, die ich würde.

  1. Erstellen Sie eine separate Class Library Projekt in meiner Lösung.
  2. Erstellen oder Hinzufügen meines .resx Dateien zu diesem Projekt.
  3. Fügen Sie ein Post-Build Event der Project Properties Dialog. (Wie unten)

Beispiel VS Post-Build-Skript:

set RESGEN="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\resgen.exe"
set LINKER="C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\al.exe"
set ASSEMBLY=$(TargetName)
set SOURCEDIR=$(ProjectDir)
Set OUTDIR=$(TargetDir)

REM Build Default Culture Resources (en)
%RESGEN% %SOURCEDIR%en\%ASSEMBLY%.en.resx  %SOURCEDIR%en\%ASSEMBLY%.resources

REM Embed Default Culture
%LINKER% /t:lib /embed:%SOURCEDIR%en\%ASSEMBLY%.resources /culture:en /out:%OUTDIR%%ASSEMBLY%.resources.dll
REM Embed English Culture
IF NOT EXIST %OUTDIR%en\ MKDIR $%OUTDIR%en\
%LINKER% /t:lib /embed:%SOURCEDIR%en\%ASSEMBLY%.resources /culture:en /out:%OUTDIR%en\%ASSEMBLY%.resources.dll


REM These are just a byproduct of using the project build event to run the resource build script
IF EXIST %OUTDIR%%ASSEMBLY%.dll DEL %OUTDIR%%ASSEMBLY%.dll
IF EXIST %OUTDIR%%ASSEMBLY%.pdb DEL %OUTDIR%%ASSEMBLY%.pdb

Wenn Sie lieber nicht verwenden Resgen.exe zu konvertierenIhre .resx Dateien, können Sie so etwas tun könnte.

using System;
using System.Collections;
using System.IO;
using System.Resources;

namespace ResXConverter
{
    public class ResxToResource
    {
        public void Convert(string resxPath, string resourcePath)
        {
            using (ResXResourceReader resxReader = new ResXResourceReader(resxPath))
            using (IResourceWriter resWriter = new ResourceWriter(
                    new FileStream(resourcePath, FileMode.Create, FileAccess.Write)))
            {
                foreach (DictionaryEntry entry in resxReader)
                {
                    resWriter.AddResource(entry.Key.ToString(), entry.Value);
                }
                resWriter.Generate();
                resWriter.Close();
            }
        }
    }
}

Eine der möglichen ziehen Rücken, um die Konvertierung auf diese Weise tun, ist die Notwendigkeit, die System.Windows.Forms.dll zu verweisen. Sie werden immer noch verwenden müssen Assembly Linker .

Edit: Wie wRAR hat uns daran erinnert, wenn Sie Ihre Baugruppen Ihre Schlüssel signieren entsprechen müssen.

Unter der Annahme, dass Sie die Standardfehlermeldung Zeichenfolgen in den Validierungs Attribute außer Kraft setzen möchten, können Sie das tun, indem Sie die ErrorMessageResourceName Einstellung und die ErrorMessageResourceType Eigenschaften wie folgt aus:

[Required(ErrorMessageResourceName = "Required_Username", ErrorMessageResourceType = typeof(MyResourceFile)]
public string Username { get; set; }

Sie können eine Ressource-Datei erstellen MyResourceFile.resx aufgerufen, die Required_Username mit der Fehlermeldung enthält, die Sie wollen.

Hope, das hilft.

Wenn der Server installiert ist nicht .NET Sprachpakete haben dann keine Rolle, was CurrentUICulture gesetzt ist, werden Sie immer Englisch in Nachrichten DataAnnotations Validierung erhalten. Diese episch Hack arbeitet für uns.

  • Gehen Sie auf "Microsoft .NET Framework 4.6.1 Language Pack" Download-Seite https://www.microsoft.com/en-us/download/details.aspx?id=49977
  • Wählen Sie die Sprache und Download
  • Extract NDP461-KB3102436-x86-x64-AllOS- {LANG} .exe mit 7-Zip
  • Extrahieren CAB-Datei x64-Windows10.0-KB3102502-x64.cab mit 7-Zip
  • Suchen "msil_system.componentmod..notations.resources _...."
  • ... in der es "system.componentmodel.dataannotations.resources.dll" findet
  • Öffnen .resources.dll mit ILSpy, suchen Sie Ressourcen und klicken Sie auf Speichern Schaltfläche oben String Tabelle als System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources zu speichern. {LANGUAGE} RESOURCES
  • Fügen Sie in Ihr Projekt unter sagen ein „Ressourcen“
  • Stellen Sie sicher, die Dateien Action Eigenschaft der Ressourcen-Dateien ist auf „Embedded Resource“

Dann in einem PreStart Methode des Projekts überschreiben Sie die System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources.resourceMan private static Feld (gesagt, es war ein Hack) mit denen, die Sie in Ihrem Projekt haben.

using System;
using System.Linq;
using System.Reflection;
using System.Resources;

[assembly: WebActivator.PreApplicationStartMethod(typeof(ResourceManagerUtil), nameof(ResourceManagerUtil.PreStart))]

class ResourceManagerUtil
{
    public static void PreStart()
    {
        initDataAnnotationsResourceManager();
    }

    /// <summary>
    /// If the server doesn't have .NET language packs installed then no matter what CurrentUICulture is set to, you'll always get English in 
    /// DataAnnotations validation messages. Here we override DataAnnotationsResources to use a ResourceManager that uses language .resources 
    /// files embedded in this assembly.
    /// </summary>
    static void initDataAnnotationsResourceManager()
    {
        var embeddedResourceNamespace = "<YourProjectDefaultNamespace>.<FolderYouSavedResourcesFilesIn>";
        var dataAnnotationsResourcesName = "System.ComponentModel.DataAnnotations.Resources.DataAnnotationsResources";
        var thisAssembly = typeof(ResourceManagerUtil).Assembly;
        var dataAnnotationsAssembly = typeof(System.ComponentModel.DataAnnotations.ValidationAttribute).Assembly;

        var resourceManager = new ResourceManager(embeddedResourceNamespace + "." + dataAnnotationsResourcesName, thisAssembly);

        // Set internal field `DataAnnotationsResources.resourceMan`
        var dataAnnotationsResourcesType = dataAnnotationsAssembly.GetType(dataAnnotationsResourcesName);
        var resmanProp = dataAnnotationsResourcesType.GetField("resourceMan", BindingFlags.NonPublic | BindingFlags.Static);
        resmanProp.SetValue(null, resourceManager);
    }
}

Ich mag eine Antwort mit der gleichen Idee schaffen, wie durch Duncan klug, aber für .NET-Core 2.2 anstelle von .NET Framework 4.x.

Hier ist es.

using System;
using System.Linq;
using System.Reflection;
using System.Resources;

public static class ResourceManagerHack
{
    /// <summary>
    /// If the server doesn't have .NET language packs installed then no matter what CurrentUICulture is set to, you'll always get English in 
    /// DataAnnotations validation messages. Here we override DataAnnotationsResources to use a ResourceManager that uses language .resources 
    /// files embedded in this assembly.
    /// </summary>
    public static void OverrideComponentModelAnnotationsResourceManager()
    {
        EnsureAssemblyIsLoaded();

        FieldInfo resourceManagerFieldInfo = GetResourceManagerFieldInfo();
        ResourceManager resourceManager = GetNewResourceManager();
        resourceManagerFieldInfo.SetValue(null, resourceManager);
    }

    private static FieldInfo GetResourceManagerFieldInfo()
    {
        var srAssembly = AppDomain.CurrentDomain
                                  .GetAssemblies()
                                  .First(assembly => assembly.FullName.StartsWith("System.ComponentModel.Annotations,"));
        var srType = srAssembly.GetType("System.SR");
        return srType.GetField("s_resourceManager", BindingFlags.Static | BindingFlags.NonPublic);
    }
    internal static ResourceManager GetNewResourceManager()
    {
        return new ResourceManager($"{typeof(<YourResource>).Namespace}.Strings", typeof(<YourResource>).Assembly);
    }
    private static void EnsureAssemblyIsLoaded()
    {
        var _ = typeof(System.ComponentModel.DataAnnotations.RequiredAttribute);
    }
}

Und ich nenne dies wie folgt:

public static void Main(string[] args)
{
    ResourceManagerHack.OverrideComponentModelAnnotationsResourceManager();
    CreateWebHostBuilder(args).Build().Run();
}

Darüber hinaus habe ich eine ~/Resources/<YourResource>.resx Datei behandelt und mit die Standardwerte und verändert sie nach Belieben. Schließlich habe ich eine leere öffentliche Klasse <YourResource>.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top