Ja, der Fehler lag bei mir... Da flog ne Exception, die die Registrierung unterbrochen hat. Die Exception wurde - aufgrund der massiven Dummheit des Entwicklers (also ich) - gefangen und als Debug-Type ins Log gefeuert (Log war natürlich auf Information gestellt). Tja, und so weiter und so weiter.
Aber das schöne bei sowas ist natürlich, dass ich viele Dinge in der Zwischenzeit über Azure gelernt habe. Ich kann z.B. sagen, dass App Services über docker-compose an sich super funktionieren
Ich kann mir beim besten Willen nicht vorstellen, wie daran die äußere Umgebung schuld sein soll oder kann.
Tja, frag mich mal
Ok, dass Azure noch eine Liste weiterer Parameter dazu gibt, wusste ich jetzt so nicht. Dann bastel ich mal ein wenig weiter und lasse mir mal alles ausgeben, was da noch so reinkommt. Kann mir auch nur vorstellen, dass da irgendwas quer schießt.
sorry zunächst, für den Betreff. Mir ist nichts besseres eingefallen. So, ich bin hier etwas am verzweifeln. Ich habe folgendes Setup
.NET 5 Web API
nuxt SPA
nginx Proxy
Alle Komponenten werden als Docker Container gebaut und in eine Azure Registry gepumpt. Ziehe ich mir jetzt lokal alle Docker Container via docker-compose in eine lokale Umgebung und starte das Ganze, funktioniert es wie erwartet und alles ist gut. Ziehe ich die nahezu identische docker-compose Datei in ein Azure AppService, verhält sich das auf einmal etwas anders. Sprich, es geht nicht
Was genau ist das Problem?
Ich nutze MediatR für das CQRS Pattern und Lamar als DI Container. Lasse ich mir beim Start der WebAPI über einen HostedService ausgeben, was alles gescannt wurde von Lamar, sehe ich alle drei Assemblies meiner Solution. Nennen wie sie mal Project.Api, Project.Models und Project.Models.SubModel. Also die Assemblies sind da und geht auch nichts verloren (was aber auch ziemlich merkwürdig wäre, da der Docker Container lokal/AppService identisch ist). Lasse ich mir auch ausgeben, was Lamar alles registriert hat, sehe ich zig "IRequestHandler<DummyRequest, DummyResponse" Registrierungen. Alle meine RequestHandler halt. Das ist lokal.
Starte ich den AppService jetzt via docker-compose und lasse mir das Log ausgeben, sehe ich auch alle von Lamar gescannten Assemblies (die drei oben), ABER es fehlen nahezu alle Registrierungen. Es ist nur ein Bruchteil von dem, was eigentlich alles dabei ist. Einzig die Registrierungen für FluentValidation sind sichtbar. Alles andere verpufft also.
Tja, und da komme ich nicht weiter. Ich sehe den Unterschied nicht und weiß nicht, wo ich ansetzen soll. Wie gesagt, der Docker Container ist identisch. Es kann also ja an sich nicht an den Binärdaten liegen. Die Konfiguration zwischen lokal/AppService unterscheidet sich nur an der BaseURL für die nuxt Anwendung und dem ConnectionString zum Azure Sql Service. Alles andere ist ebenfalls identisch.
Woran kann das liegen, dass Lamar einfach nichts findet, obwohl er die gleichen Assemblies scannt?
Oder ist das noch ne Macke von den AppServices, da docker-compose noch experimentell ist?
so, ich hab mir das jetzt alles mal versucht weiter detailliert anzuschauen. Sobald man eine eigene Implementierung des AuthenticationStateProviders in die Services legt und gleichzeitig die von MS zur Verfügung stehenden Extensions "AddApiAuthorization" oder "AddOidcAuthorization" verwendet, knallt es an jeder Ecke. Scheinbat castet er im Hintergrund immer auf die von ihm eigentlich injizierte Instanz des AuthenticationStateProviders.
Auch wenn es wahrscheinlich bekloppt ist, habe ich jetzt angefangen eine eigene Implementierung rund um die oidc-client Library zu schreiben und nicht die von MS bereitgestellten Mittel zu verwenden.
Aber da es eh meine ersten Gehversuche in Blazor sind, ist das ein ganz nettes kleines Projekt um besser die Mechaniken in Blazor zu verstehen.
ich beschäftige mich seit geraumer Zeit mit Blazor und bin jetzt an dem Punkt angekommen, meine Test-Anwendung gegen einen IdentityServer4 zu authorisieren. Das funktioniert sogar auch problemlos. Allerdings stoße ich gerade auf ein Problem, zu dem ich nichts finde, oder ich einfach nur falsch verstehe.
Also, wenn der JWT Token vom ID4 zurückgeliefert wird, wird diese Information in den Session Storage geschrieben. Sprich, wenn ich den Browsertab schließe und einen neuen öffne, muss ich mich erneut einloggen. Das ist natürlich später für die User nicht tragbar. Blazor nutzt im Hintergrund die oidc-client.js Library. In einer vorherigen Test-Anwendung über vuejs konnte man in den UserSettings des oidc-clients den userStore mit angeben:
"userStore": new WebStorageStateStore( { store: localStorage }
Diese Möglichkeit scheint es innerhalb von Blazor nicht zu geben. Innerhalb der BlazorApp initialisiere ich die Services via
In der oidc.json stehen alle weiteren Metainformationen
{
"authority": "https://localhost:5000",
"client_id": "blazor",
"redirect_uri": "http://localhost:5001/authentication/login-callback",
"post_logout_redirect_uri": "http://localhost:5001/authentication/login-callback",
"response_type": "code",
"scope": "openid profile email",
"userStore": "new WebStorageStateStore({ store: localStorage})" // das geht hier so natürlich nicht
}
Hier kann der userStore nicht überschrieben werden, da es hier ja als String interpretiert wird.
Weiß irgendwer, wie ich Blazor (bzw. den oidc-client dahinter) dazu verdonnere, den localStorage zu verwenden anstatt den sessionStorage? Oder macht man das erst gar nicht? Und wenn ja, wie schaffe ich es das der User sich nicht jedesmal neu anmelden muss?
Warum erstellst du erst eine List<ListViewItem> und fügst die Elemente dort ein? Warum nicht in der Schleife gleich per "lv.Items.Add(neu)". Die Methode AddRange nimmt ein Array ListViewItem entgegen. Deine markierte Zeile müsste also lauten "lv.Items.AddRange(arrayItems.ToArray())".
auch wenn ich ThomasE. zustimme, dass solch Notifications eigentlich in den Service selber gehören, kann man solche Fälle lösen, wenn man z.B. eine Message Queue verwendet: MSMQ and SQL Server Integration
relational kann man sowas auch abspeichern und an sich ohne weiteres abfragen. Auch hier hängt dementsprechend ein Analysis Cube oder ähnliches Gebilde hinten dran. Auf Rohdaten, wie Abt schon geschrieben hat, würde ich es aber auch nicht los lassen.
Ich habe solch eine "Fußball-Struktur" selber noch nie relational designt, würde aber auch daruf tippen, dass die Tore relational gesehen eine eigene Tabelle ist. Denn nur so, wie du ja selber auch schon festgestellt hast, können beliebig viele weitere Statistiken angehängt werden (Spieler, Minute, aus ruhenden Ball, usw...).
Zitat
Man nehme mal an, man habe eine Tabelle mit ganzen Zahlen, ein paar hängen zusammen, also folgen aufeinander, aber es gibt auch Lücken auf dem abgebildeten Zahlenstrahl.
Neue Tabelle erzeugen mit gleicher Struktur nur mit IDENTITY. Tabelleninhalt rüber schubsen (INSERT INTO x SELECT FROM y). Alte Tabelle droppen. Neue Tabelle umbennenen. Alle Constraints wieder aktivieren.
exec sp_MSforeachtable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT ALL"
DB wieder in MULTI USER versetzen. Je nach Datenmenge ist das ziemlich schnell gemacht.
welche Datenbank man nehmen sollte, hängt sehr stark vom Anwendungsfalls ab. Vielleicht reicht schon eine Sqlite DB, oder du brauchst ein SQL Server Enterprise. Sprich, die Range geht von minimal bis ins extreme. Vielleicht ist auch eine NoSQL DB sinnvoller? Auch deine Anforderungen sind nicht bekannt. Auf was für einem OS soll die DB laufen? Von wie viel Daten sprechen wir? Wie viele Zugriffe pro Sekunde? Usw usw...
Zitat
Die Tabelle komplett auf einen Datagrid laden und dort filtern, oder direkt bei der Abfrage filtern?
Auch wenn du noch am Anfang stehst, solltest du dir die Frage selber beantworten können :)
Und nebenbei: Wenn du eine Anwendung bauen willst, die es als Desktop und Webanwendung gibt, wirst du an einer Web API (z.B. ASP .NET Core) nicht vorbeikommen. In dieses Thema solltest du dich unbedingt einlesen. Anhand deiner Fragen erkennt man schon, dass du noch recht am Anfang stehst (was ja absolut nicht schlimm ist). Hier würde ich dir empfehlen, dass du dich erst weiter in die Grundlagen vertiefst, da gleich solch ein Anwendungsfall sich nicht unbedingt als Startprojekt eignet. Außer es ist eine reine "Spielwiese" für sich.
Ok, in der Zwischenzeit hat Stefan.Haegele geantwortet. Aufgrund deiner Antwort stellt sich immer noch die Frage, ob es eher relationale Daten sind (SQL) oder eher strukturierte (NoSQL)?
Den Toad Data Modeler kann ich nur empfehlen. Lohnt sich aber auch erst, wenn man schon ein relativ "mächtiges" Schema vor sich hat. Für ein paar Tabellen ist das Ding zu oversized. Jedenfalls meiner Meinung nach.
Wenn es nicht unbedingt per ODP sein muss, würde ich den ManagedDriver von Oracle empfehlen. Das Ding ist nur 5MB groß und reicht vollkommen aus. Ansonsten schleppt man immer ein über 100MB großen Client mit sich rum.
du musst die Einträge dem Dictionary hinzufügen, da du diese ja auch per BindingSource bindest. Die ListBox bindet sich ja an das Dictionary. Wenn du jetzt Elemente direkt zur ListBox hinzufügst, weiß die ListBox ja nicht mehr was sie zu tun hat, da sie ja den Eintrag nicht selber in das Dictionary schreiben kann. Hoffe das war verständlich :)
Hinzu kommt ja, dass MS sich auch für die neuen Rechenzentren auch der DSGVO verpflichten. Dass ist eigentlich der wichtigste Punkt. Wo der Server steht, ist mir insgesamt egal. Leider nicht den anderen. Da kann ich Abt nur zustimmen. Reine Sturheit...
Azure soll im vierten Quartal des Kalenderjahres 2019 allgemein verfügbar werden. Office 365 soll im ersten Quartal Kalenderjahr 2020 folgen sowie Dynamics 365 im Laufe des Jahres 2020.
Zitat
Aufgrund dieser veränderten Kundenanforderungen werden die neuen Cloud-Regionen nun den Schwerpunkt unserer Cloud-Strategie in Deutschland bilden
Die "Deutschland-Cloud" beginnt erst. Sie ist "nicht mehr" für Neukunden verfügbar, sondern "erst bald" für Neukunden verfügbar.
[Edit]: Achso. Es regen sich jetzt alle auf, dass es nicht mehr "Microsoft Deutschland Cloud", sondern dann nur noch "Microsoft Azure" in Deutschland ist. Da verstehe mal jemand die Aufregung...
WITH Bla AS
(
SELECT
CASE WHEN x = y THEN 1 ELSE 0 END AS Wert1
CASE WHEN y = z THEN 1 ELSE 0 END AS Wert2
FROM Tabelle
)
SELECT * FROM Bla
WHERE Wert1 = 0
Solange die Excel-Datei auf dem Server liegt, ist das kein Problem (z.B. mit NPOI, oder das genannte OpenXML). Wenn die Datei auf dem Client liegt, muss diese natürlich erst zum Server hochgeladen werden, dann manipuliert werden, und dann wieder heruntergeladen werden.
@crazyyzarc:
Es macht einfach absolut kein Sinn irgendwas vor eine Variable zu setzen. Warum auch? Was soll das bringen? Ich verstehe es einfach nicht :)
So um 1990 herum, wo es noch keine wirklich guten ausgearbeiteten IDEs gab und man eher mit nem Notepad programmiert hat, da habe ich tatsächlich Prefixe verwendet. Aber heute? Da nehmen die IDEs doch ein alles ab. Mouse Hover drüber und ich weiß welcher Typ (nutze konsequent var), rechtklick zur Deklaration, usw usw. Da braucht man definitiv keine Prefixe mehr und diese sind - zu recht - heute eher total verpönt.
Und das aller aller wichtigste: Einfach eine Variable so benennen, dass man gleich weiß was die "vor hat". Es gibt keine Zeichenbegrenzung bei Variablennamen :)
was haltet ihr davon, Objektvariablen mit einem @ - beginnend zu bennen?
Gar nichts :)
Das @ wird verwendet um ggf. Variablen zu erstellen, die so heißen wie Schlüsselwörter. Also z.B. @event, oder @public. Vor allen Variablen ein @ zu kloppen ist, naja, ziemlich mies. Und ganz ehrlich, man sieht auch so wo Variablen verwendet werden, da brauche ich kein @ davor stehen zu haben. Mich persönlich würde das massiv verwirren und das Ganze extrem unleserlich machen.
Aber es ist halt auch keiner da, der das ... einfach so weiss ... wie man das coden muss, so wie ich mir das gedacht hatte
Das kann man jetzt so nicht sagen, du verstehst es nur nicht :) (nicht böse gemeint).
Der gepostete Code von Taipi sieht schon ganz gut aus. Der wird das Notify einfach über alle Laufwerke gezogen. Reicht ja auch vollkommen aus. Das kompiliert bei dir natürlich so nicht, da du die Methoden noch definieren musst. Die kennt .NET so nicht, da es sich um direkte Win32 API Aufrufe handelt. Die Signaturen der Methoden kannst du auf PInvoke nachlesen.
hier kann nicht SHCNF_IDLIST verwendet werden. Dieser Parameter sagt aus, dass in dwItem1 eine ITEMIDLIST Struktur erwartet wird. Sprich, ein IntPtr auf ein PIDL. Du gibt's aber einen konkreten Pfad rein (String). Du musst SHCNF_PATH verwenden. Wenn du unbedingt eine ITEMIDLIST benötigst, musst du dir diese über ILCreateFromPath besorgen.