Laden...

ASP.NET Core speichert Währung falsch, zeigt sie aber richtig an

Erstellt von NEUMee vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.568 Views
N
NEUMee Themenstarter:in
24 Beiträge seit 2011
vor 5 Jahren
ASP.NET Core speichert Währung falsch, zeigt sie aber richtig an

Hallo Leute,

ich versuche mich gerade an einer MVC Webanwendng mit ASP.NET Core 2.2.
Die Kommunikation mit der MySql-Datenbank wird mit dem Provider "MySql.Data.EntityFrameworkCore" abgewickelt.

Die Datenbank habe ich mit EF und Database First in Model-Klassen gemappt.
Funktioniert Alles ganz toll, aber:

Ich habe ein Problem mit einem Feld, wo ich datenbankseitig eine Währung speichere.
In MySql habe ich dafür den Datentyp DECIMAL(8,2) mit den Eigenschaften UNSIGNED und DEFAULT(0) für das Feld vereinbart.

Model:

[DataType(DataType.Currency)]
[DisplayFormat(DataFormatString = "{0:C}", ApplyFormatInEditMode = true)]
public Decimal Nettokaufpreis { get; set; }

View:

<div class="form-group">
	<label asp-for="Nettokaufpreis" class="control-label"></label>
	<input asp-for="Nettokaufpreis" class="form-control" />
	<span asp-validation-for="Nettokaufpreis" class="text-danger"></span>
</div>

Wenn ich jetzt mein z.B.: Edit-View im Browser anschaue, dann wird der Wert aus der DB sauber angezeigt - also z.B.: 81,90 €.
Die Anwendung erkennt also, bei der Ausgabe der Daten, welche Landeswährung auf dem Server eingestellt ist.
Aber, wenn ich den Wert nun ändere, darf ich kein Komma und kein €-Zeichen verwenden, weil er ja einen Zahlenwert (Decimal) verlangt.
Nur, wenn ich z.B.: 90.00 eingebe (was 90,00 € repräsentieren sollte), wird der Wert verarbeitet.
Allerdings speichert es in der Datenbank den Wert 9000.00 was ja auch wieder falsch ist, denn beim nächsten Aufruf wird 9.000,00 € im View angezeigt.

Beim Darstellen der Währung wird ja die richtige Landeswährung herangezogen (GET), warum funktioniert das beim Speichern (POST) nicht ebenso unkompliziert.

Was mache ich falsch?
Muss ich das Feld in der Modelklasse evtl. als String definieren und den Eingabewert, vor dem Speichern in die DB, umwandeln (Klingt aber gefühlt falsch!)?
Ich komme da ohne Hilfe nicht weiter.
Könntet ihr mir bitte weiterhelfen oder einen Tipp geben, wo es Informationen dazu gibt?

Vielen Dank, NEUMee!

16.841 Beiträge seit 2008
vor 5 Jahren

Du musst bei jedem Request die Culture des Clients beachten. Der Server selbst sollte immer "neutral" sein.
Globalisierung und Lokalisierung in ASP.NET Core

Ansonsten bekommt man - wie zB ich oft - Probleme mit Webseiten.
Grund: ich habe ein englisches System - bin jedoch wegen falsch programmierter Anwendungen und Webseiten gezwungen eine deutsche Region zu hinterlegen.
Ansonsten funktionieren die Ein- und Ausgaben nicht richtig, weil Cultures nicht einheitlich verwendet werden.
(Mein aktuelles Beispiel aufgrund des jährlichen Steuerzyklus: WISO Steuer macht ganz komische Dinge, wenn man keine deutsche Region hinterlegt hat...schon lange gemeldet - interessiert dort nur leider irgendwie niemand. Und das sind einfach Basics jedes Entwicklers!).

Auch ist der Titel falsch: das hat nichts mit der Währung, sondern mit einfacher Culture (Komma, Punkt) zutun.

Reminder: das gilt auch für Zeiten!

N
NEUMee Themenstarter:in
24 Beiträge seit 2011
vor 5 Jahren

Hallo nochmal,

also, ich habe versucht das zu verstehen - muss aber zugeben, dass mir das nicht in den Kopf will.

Meine Startup.cs enthält diese ConfigureServices() Methode:


// This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            // alle Ressourcendaten werden im Verzeichnis "Resources" gespeichert
            services.AddLocalization(opts => { opts.ResourcesPath = "Resources"; });

            services.AddMvc()
                .AddViewLocalization(opts => { opts.ResourcesPath = "Resources"; })
                .AddViewLocalization(LanguageViewLocationExpanderFormat.Suffix)
                .AddDataAnnotationsLocalization()
                .SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            services.Configure<RequestLocalizationOptions>(opts =>
            {               
                var supportedCultures = new List<CultureInfo>
                {

                    //new CultureInfo("fr-FR"),      // Französisch
                    //new CultureInfo("zh-CN"),      // Chinesisch
                    //...
                    new CultureInfo("de-DE")         // Deutsch
                    //...                  
                };

                // hier wird die Standard Sprache gesetzt
                opts.DefaultRequestCulture = new RequestCulture(culture: "de-DE", uiCulture: "de-DE");
                //opts.SetDefaultCulture("de-DE");
                
                // zum Formatieren von Zahlen, Datum usw.
                opts.SupportedCultures = supportedCultures;
                
                // zum Formatieren des UI
                opts.SupportedUICultures = supportedCultures;
            });

            services.AddDbContext<db_hardware_devContext>(options => options.UseMySQL(Configuration.GetConnectionString("MySqlConnectionString")));
        }

Im Edit View habe ich folgendes ergänzt:


@using Microsoft.AspNetCore.Mvc.Localization
@inject IViewLocalizer Localizer

Nur wie nutze ich im Formular dann den Localizer?


<!-- Lokalisierungseinstellungen sollen hier (Währung) berücksichtigt werden -->
<div class="form-group">
    <label asp-for="Nettokaufpreis" class="control-label"></label>
    <input asp-for="Nettokaufpreis" class="form-control" />
    <span asp-validation-for="Nettokaufpreis" class="text-danger"></span>
</div>

Also so in der Art: @Localizer["Nettokaufpreis"] irgendwie.

Ziel soll sein, dass man den Wert mit Komma, also bspw. 77,99 € eingibt, aber intern 77.99 als Value des Input Elements gepostet wird, welchen die Datenbank dann aufnehmen kann.

Macht das Alles der Localizer-Dienst für mich, oder muss ich da controllerseitig noch umwandeln?

Ich bin für jede Info dazu dankbar!

LG