Laden...

Forenbeiträge von Rioma Ingesamt 228 Beiträge

26.09.2017 - 20:26 Uhr

Alles klar danke.

@Abt dein neues Beispiel auf Github hilft sehr! Github

14.09.2017 - 21:11 Uhr

warum nicht? Mit dem wäre das Problem schon gelöst.

Das Backend hat einen kleinen Funktionsumfang und muss relativ häufig installiert werden (Jedes mal liegt eine andere Datenbank mit Benutzern dahinter). Um den Aufwand möglichst gering zu halten, wurde sich damals für das Paket AspNet.Security.OpenIdConnect.Server entschieden, was mit dem Backend ausgeliefert wird.
Außerdem würde ein für sich laufender IdentityServer die Ausfallsicherheit nicht besonders erhöhen, da nun lediglich der IdentityServer ausfallen müsste, um die Applikation unbrauchbar zu machen.

warum nicht? Mit dem wäre das Problem schon gelöst.

Der IdentityServer würde ein Token ausstellen und ich würde in der Web API den IdentityServer als Issuer eintragen. Woher wissen die einzelnen API´s, das dass Token gültig ist? Ich nehme an, der IdentityServer muss nicht bei jedem Request gefragt werden.

Ich durchsuche gerade die Spezifikation des OpenID Connect Protokolls um eine Antwort zu finden. Allerdings wird es mir noch nicht 100% klar.

Hast du dann bei deiner OpenId-Variante ein Authentifizierung gegen was?

Die Applikation läuft stets in einem internen Netzwerk und die Credentials werden gegen eine Datenbank geprüft. Es ist quasi ein Resource Owner Password Credentials Flow.

Vielen Dank

14.09.2017 - 18:23 Uhr

Hallo zusammen,

was ist der übliche Weg um einen REST-Service mit Token-Authentifizierung zu skalieren?

Ich muss natürlich sicherstellen, dass ein Benutzer mit jedem Backendseitigem Service sprechen kann, egal bei welchem er sich angemeldet hat.

Daher muss das Token von jedem Service für gültig gehalten werden.

Es wird zurzeit kein eigenständiger IdentityServer eingesetzt, sondern eine relativ kleine Bibliothek: ASP.NET.OpenId die in der eigentlichen Applikation sitzt.

Was habe ich nun für Möglichkeiten?

  1. Token auf Basis eines festen Zertifikats erstellen. Das Zertifikat bekommt dann jede Instanz des Services und sollte so kompatible Tokens erzeugen
  2. Ich habe ansetze mit Redis als "Key-Store" gesehen

Habt ihr Erfahrungen und könntet mich beraten?

Vielen Dank

28.08.2017 - 16:39 Uhr

Alles klar, danke für die Erklärung!

28.08.2017 - 13:00 Uhr

Das heißt ich schütze die Daten des Servers gegen unerlaubte Browser-Clients?

Ich habe es nicht getestet, aber gehe davon aus, dass ich außerhalb des Browsers die Header ohne Probleme ignorieren kann.

28.08.2017 - 09:35 Uhr

Hallo zusammen,

ich bräuchte mal eine Klarstellung bezüglich CORS.

Ich habe bereits einige Erklärungen gelesen, allerdings ist bisher nicht alles klar.

Ausgangspunkt: Frontend und Backend laufen nicht unter der gleichen origin.

Damit die SOP nicht verletzt wird, muss ich nun über die entsprechende CORS-Middlware für ASP.NET Core die richtigen Header setzen lassen.

Somit ist der Zugriff auf das Backend kein Problem.

Aber an welcher Stelle wird nun die Sicherheit erhöht? (Clientseitig, Serverseitig)

Ich würde vermuten, dass damit der Client im Browser geschützt werden soll. Aber unter welchen Bedingungen ist die Sicherheit höher?

Vielen Dank.

03.08.2017 - 12:57 Uhr

Da es sich vom eigentlichen ADO.NET Kommunikationparadigma unterscheidet, ist es für mich in diesem Sinne schon ein Bug; egal was die andere Seite als Grund darstellt.

Demnach hatte ich mich richtig erinnert, dass dies z.B. beim SQL-Server nicht zu Problemen führt?

Wechsel der Datenbank ist leider keine Option.

Ich werde mal mit der Lifetime der Connections hantieren und im Notfall Richtung eigenem Connection-Pooling testen.

Sehr ärgerlich.

03.08.2017 - 11:37 Uhr

Ist es denn deiner Meinung nach ein Bug? Da in dem Issue-Tracker von "expected behavior" gesprochen wird.

Wenn ich mich richtig entsinne, passiert mir das mit dem SQL-Server nicht. Allerdings habe ich momentan keinen zum testen.

Kann jemand bestätigen, dass z.B. das neustarten des SQL-Servers mit über Connection-Pooling verbundenem Backend keine Probleme macht?

03.08.2017 - 10:09 Uhr

verwendetes Datenbanksystem: Firebird

Hallo zusammen,

wir benutzen momentan ein Backend auf ASP.Net Core Basis in zusammenspiel mit Firebird.
Connection-Pooling ist aktiviert. Sollte nun die Datenbank

  1. kurzzeitig nicht erreichbar sein
  2. ein Attachement über die DB geschlossen werden
  3. aus welchen Grund auch immer eine Connection wegbrechen

geht nichts mehr.

Der Grund ist folgender: > Fehlermeldung:

FirebirdSql.Data.FirebirdClient.FbException: Error reading data from the connection.

Laut diesem Issue, ist das das vorgesehene verhalten: http://tracker.firebirdsql.org/browse/DNET-585?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel

Mir fallen nun nur 2 "Lösungen" ein:

  1. Connection-Pooling deaktivieren (würde ich nicht unbedingt als Lösung sehen)
  2. Die Exception fangen, den Pool leeren und den SQL erneut absetzen

Beim leeren des Connection-Pools wäre nur die eine Anwendung betroffen und keine anderen.

Habt ihr bessere Ideen?

Danke und Grüße

08.05.2017 - 14:51 Uhr

Wir nutzen seit längerem das Mutlilingual App Toolkit für Wpf (WinForms sollte auch kein Problem sein) --> https://marketplace.visualstudio.com/items?itemName=MultilingualAppToolkit.MultilingualAppToolkitv40

Wir schicken dann die standardisierten XLIFF Exporte (falls nötig) an ein Übersetzungsbüro und müssen dann nur die bearbeitete Datei einbinden. Zugriff auf die übersetzten Texte erfolgt dann über die Ressourcen-Dateien.

Auch automatische Übersetzungen sind möglich, aber die bewegen sich meist auf google translator Niveau.

24.04.2017 - 15:46 Uhr

Hallo Abt,

könntest du nochmal genauer erklären inwiefern die Usersecrets helfen?

Ich hatte es so in Erinnerung, dass die Usersecrets im "Benutzer-Ordner" abgelegt werden und so zum Beispiel verhindert wird, dass diese mit eingechecked werden.
Eine Verschlüsselung würde demnach nicht dahinter stecken.

Es ist also eher eine Absicherung während dem Entwicklungsprozess und keine ConnectionString Verschlüsselung für den Relase-Build.

Vielen Dank

09.04.2017 - 17:24 Uhr

Alles klar. Vielen Dank für die Informationen!

09.04.2017 - 13:16 Uhr

Hallo zusammen,

ich habe bisher perfmon genutzt um .NET Prozesse zu überprüfen. Es geht mir speziell um die GC-Abläufe. Ich habe gelesen, dass die Performancecounter bisher im .NET Core Bereich nicht vorhanden sind. Bedeutet dies, dass somit der perfmon zur Überprüfung rausfällt?
Gibt es alternativen, die ihr empfehlen würdet?

Vielen Dank

30.01.2017 - 11:45 Uhr

Hallo zusammen,

ich habe nochmal folgende Anforderung:

Lesen einer Excel-Datei --> Aufbereitung der Daten --> Update/Insert in DB --> Senden einer Status-E-Mail.

Ich habe mir einige Gedanken gemacht und bräuchte nun eure Hilfe.

Hier meine Gedanken:

Typisches Pipeline-Probleme --> Verwendung von TPL-Dataflow
Lesen der Datei außerhalb des "Dataflows"
Post in einen Transformlock für Aufbereitung der Daten
Weitergeben an einen ActionBlock für Update oder Insert

Meine Fragen:

  1. Ich würde die einzelnen Datensätze pro Datei in Batchblöcke zusammenfassen und dann im ActionBlock parallel abarbeiten und pro "Batch" nur eine Transaction nutzen.

Wo fange ich an die Blöcke zu bilden? Bereits beim Einlesen der Datei? Dann hätte ich mehrere Posts in den TransformBlock pro Datei. Oder setze ich einen BatchBlock zwischen Transformer und Action? Allerdings müsste ich dann den BatchBlock hin und wieder manuell auslösen, da die Excel-Datei selten genau ein vielfaches der "Max-Size" des BatchBlocks haben wird.

Wie kann ich optimal bestimmten, wenn die Datei vollständig importiert wurde? Durch die Blockbildung wird dies komplizierter.

Oder sollte ich auf die Blockbildung und parallele Verarbeitung pro Datei verzichten?

  1. Der ActionBlock ist mit dem Import momentan das letzte Glied im "Dataflow". Wie verfahre ich am besten mit der EMail? Die EMail kann entweder eine Erfolgsmelung oder eine Errormeldung enthalten. Sollte ich hier einen weiteren Block verwenden, oder das Versenden aus dem "Dataflow" herausnehmen? Eine Verarbeitung über eine kleine Warteschlange mithilfe der BlockingCollection wäre ebenfalls eine Möglichkeit.

Ihr seht ich bräuchte Hilfe bei einigen "Design-Entscheidungen".

Ich hoffe ihr könnt mich ein wenig unterstützen.

Vielen Dank

21.12.2016 - 11:40 Uhr

Danke für eure Hilfe! Ich werde die Umgebungsvariablen nutzen.

20.12.2016 - 20:27 Uhr

Hallo zusammen,

ich habe mich die letzten Tage mit Docker beschäftigt und hätte eine Frage zu den Appsettings.

Als Beispiel ohne Docker: Ein Pfad (zum Beispiel zu einer Datenbank) ist in den Appsettings gespeichert. Ändert sich der Pfad, ist das kein Problem. Ich ändere entsprechend den Pfad in der Datei und bin fertig.

Bei Docker habe ich jetzt x alternativen alle mit Vor und Nachteilen.

  • Umgebungsvariablen nutzen
  • Shared-Folder
  • Jedesmal ein neues Image erstellen
  • ..... vielleicht weitere.....

Wie geht ihr mit dem "Problem" um?

Danke

27.10.2016 - 16:43 Uhr

Es ist im JSON Format zwar nicht vorgesehen, aber JSON.Net unterstützt doch zum Beispiel Kommentare.

31.08.2016 - 16:29 Uhr

Ich hatte anfangs nicht daran gedacht, allerdings dann hinzugefügt.

Funktionieren tut es aber nur, wenn das Hashset static ist. Woran liegt das?
Ohne static befindet sich die variable auf Instanz-Ebene und davon sollte es nur eine geben.

Erzeugt wird diese von Topshelf:


   HostFactory.Run(config =>
            {
                // Pass it to Topshelf
                config.UseSimpleInjector(_container);
                config.UseNLog();

                config.Service<Service>(s => //Service ist die Instanz
                {
                    s.ConstructUsingSimpleInjector();
                    s.WhenStarted((service, control) => service.Start(control));
                    s.WhenStopped((service, control) => service.Stop(control));
                });

                config.RunAsLocalSystem();                            

            });

31.08.2016 - 15:46 Uhr

Das ich das nicht verhindern kann, ist mir bewusst.

Deswegen habe ich versucht, das Problem mit dem Hashset zu umgehen. Allerdings ohne erfolg. Ich bekomme 2 Mal ein true zurück und am Ende ist der Pfad nur einmal drin.

Füge ich die Datei nun ein weiteres Mal hinzu, gibt es keine Probleme. Die events sind einfach zu kurz hintereinander.

31.08.2016 - 14:24 Uhr

Gelöst leider nicht. Ich wollte damit nur sagen, dass mein Problem nicht von den expliziten Eventhandlern kommt.

Absolut letzte Option wäre RX:


var watcher = new FileSystemWatcher("./");

Observable.FromEventPattern<FileSystemEventArgs>(watcher, "Changed")
            .Throttle(new TimeSpan(500000))
            .Subscribe(HandleChangeEvent);

watcher.EnableRaisingEvents = true;

Aber ich füge eine lib natürlich ungern für eine einzige Stelle hinzu.

Edit: Der Code ist aus dem Link

31.08.2016 - 14:12 Uhr

Deabonnieren ist keine Option, da so potentielle andere Dateien übersehen werden.

Die Abfrage des booleschen Wertes müsste aber auf Dateiebene stattfinden. Da andere Dateien natürlich noch verarbeitet werden sollen. Ich denke ich werde hier ebenfalls das Problem haben, dass dies zu langsam ist.
Das Event habe ich nicht explizit abonniert.


 _fileSystemWatcher.Created += FileSystemWatcherOnCreated;

Ich denke mein Problem ist hier erklärt:

FileSystemWatcher Changed event is raised twice

31.08.2016 - 13:47 Uhr

Hallo zusammen,

ich habe ein kleines Problem mit dem Verhalten des FilesystemWatchers. Bekanntlich werden für eine Datei die Events häufig mehrfach gefeuert (Es geht nur um das OnCreated).

Ich würde das Event aber gerne nur einmal verarbeiten, bis die Datei wieder von mir "freigegeben" wurde.
Ich habe im Handler ein Hashset erstellt und füge den Pfad hinzu. Sollte das fehlschlagen, würde die eigentliche Aktion nicht ausgelöst werden.


 private HashSet<string> files = new HashSet<string>();

        private void FileCreated(object sender, FilePathEventArgs e)
        {
            try
            {
                if (files.Add(e.FilePath))
                   //aktion();
            }
            catch (Exception ex)
            {
//Test
            }

        }

Die Add Funktion ist natürlich nicht atomar und die Events werden so schnell gefeuert, das die Aktion dennoch 2 Mal ausgeführt wird.

Hat jemand eine andere Idee?

Danke

25.08.2016 - 16:35 Uhr

Als alternative zu ILMerge wäre noch Costura.Fody zu empfehlen. Du installierst das Nuget-Package und bist fertig. Die kompilierte exe enthält sämtliche Abhängigkeiten und du brauchst die dll's nicht daneben liegen haben.

Wenn du deine Projekt-Datei anpasst:

<Target 
    AfterTargets="AfterBuild;NonWinFodyTarget"
    Name="CleanReferenceCopyLocalPaths" >
     <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>

Bekommst du auch noch ein sauberes Output-Directory.

07.08.2016 - 16:43 Uhr

Die Verwendung von einem Predicate lässt sich eigentlich sehr gut nachlesen. Ein Predicate ist für gewöhnlich ein delegate vom Typ Func<T,bool>.

Die Frage ist also, wie kann ich einen delegate definieren und an eine Methode übergeben.


   // 1)
            Predicate<string> myFilter2 = delegate (string city) { return city.Contains('A'); };
            CityFilter(myFilter2);

            // 2)
            Predicate<string> myFilter = city => city.Contains('A');
            CityFilter(myFilter);

            // 3)
            CityFilter(city => city.Contains('A'));

25.07.2016 - 20:46 Uhr

Danke nochmal für die ausführliche Hilfe.

Eine Frage ist mir mittlerweile noch gekommen. Wie würdest du unterschiedliche Sprachen handhaben?

Die Services, die die Nachrichten über den Pushservice rausschicken möchten, wissen ja so erstmal nichts von der Client-System-Sprache und immer ist das vielleicht auch nicht möglich. In der Hand des Pushservices sollte dies wohl auch nicht liegen die Nachrichten zu "übersetzen".
Sollte das Übersetzen beim Client liegen, könnten nur standardisierte Nachrichten rausgeschickt werden wie zum Beispiel: "UploadStatusOk" wird zu "Datei erfolgreich hochgeladen" oder eben das ganze auf Englisch.

Ich drehe mich momentan ein wenig im Kreis. Vielleicht hättest du ja nochmal einen Tipp.

Danke

15.07.2016 - 09:20 Uhr
13.07.2016 - 09:23 Uhr

Ich habe es so verstanden, dass die Kommunikation (bzw. der "Kommunikationsstart") in beide Richtungen gehen soll, oder vertue ich mich? Demnach wäre SignalR die bessere Alternative.
Allerdings hat der JavaClient wohl ein paar Fehler und seit längerem wird nichts mehr daran gemacht: https://github.com/SignalR/java-client Aber vielleicht ändert sich das ja mit SignalR3 wieder.

15.06.2016 - 09:40 Uhr

Was auch immer 'video' ist, für mich sieht das so aus, als würdest du der Variabel immer nur ein Bitmap zuweisen?



  void FinalVideo_NewFrame(object sender, NewFrameEventArgs eventArgs)
        {

            if (stopVideo==true)
            {
                2) Erst wenn du das Video stoppst, wird video (1 Bitmap) dem AVIwriter hinzugefügt
                video = (Bitmap)eventArgs.Frame.Clone();
                AVIwriter.Quality = 0;
                AVIwriter.AddFrame(video); //addd new frame to pend video file
            }
            else
            {
    1)            video wird ein Bitmapt zugewiesen
                video = (Bitmap)eventArgs.Frame.Clone();
            }
        }


31.05.2016 - 22:36 Uhr

Stichwort ist der logische UND Operator --> "&&".

Dies sind allerdings Grundlagen, die du erst erlernen solltest. Du wirst bessere Erfolge erzielen, wenn du dir die Grundlagen selbst bei bringst.

Schau mal hier:
1.http://openbook.rheinwerk-verlag.de/visual_csharp_2012/ 1.http://www.guidetocsharp.de/

Edit: Sorry. Trotz Warnung beim Beitrag speichern hab ich den Post von MrSparkle übersehen...

24.05.2016 - 15:58 Uhr

Dein "MainViewModel" ist da schon richtig. Du könntest über dein MainViewModel eine Auflistung von mehreren "TabViewModels" nach außen geben. Jedes ViewModel entspricht dabei einem Tab bzw. einem UserControl.

Dein TabControl bindest du dann an diese Auflistung.

Nun musst du festlegen, welches UserControl zu welchem ViewModel gehört.

Dazu legst du ein DataTempalte pro TabView/TabViewModel an:


<DataTemplate DataType="{x:Type :TabViewModel1l}">
    <vw:View1 />
  </DataTemplate>

19.05.2016 - 11:12 Uhr

Bei WebFrameworks solltest Du Dir auch anschauen, wer hinter den Projekten steckt.
Hinter Aurelia sind ein paar Entwickler. Hinter AngularJS steckt Google, hinter Bootstrap steckt Twitter, hinter ReactJS steckt Facebook.
Alles Firmen, die unheimlich viel Geld rein stecken und eine entsprechende Langlebigkeit höchst-wahrscheinlich ist.

Bei Aurelia finde ich es schon komisch, dass sie auf ihrer Webseite auch ihre Entwickler als Consultants anbieten.
Hat irgendwie einen Beigeschmack.

WebFrameworks ansonsten kommen und gehen leider ziemlich oft wie Eintagsfliegen.){gray}

Hinter Aurelia steck Durandal.Inc. Soweit ich weiß, gibt es die seit ca. 20 Jahren? Natürlich ist das nicht Google. Da Aurelia aber ein offizielles Produkt ist und Durandal.Inc mit zusätzlich angebotenen Services* für Aurelia Geld verdienen möchte, gehe ich davon aus, dass Aurelia nicht einfach wieder "verschwindet".

Ich glaube man muss keine Berührungsängste bezüglich Aurelia haben. Oder siehst du das völlig anders Abt?

*Mit Services meine ich zum Beispiel Premium-Support oder das Produkt Aurelia-Interface. Das Framework an sich bleibt frei benutzbar.

19.05.2016 - 10:20 Uhr

Zu 2. Für gewöhnlich braucht man die JQuery-Bibliothek allerdings bei SPA Frameworks wie Angular nicht (oder man muss es aufgrund von Abhängigkeiten leider einbinden, benutzt es aber selber nicht. Angualr nutzt intern jqlite soweit ich weiß). Für Bootstrap gibt es zum Beispiel Controls die nativ in Angular geschrieben wurden: https://angular-ui.github.io/bootstrap/

Sollte dir Angular 2 nicht so gefallen, empfehle ich dir Aurelia. Robert Eisenberg, damaliger Angular 2 Team-Member, hat Angular verlassen und arbeitet nun an dem SPA-Framework Aurelia. Mir gefällt dies deutlich besser --> Das Framework rückt nicht so in den Vordergrund, du sparst viel Konfigurationsaufwand wenn du dich an die Konventionen hältst. Außerdem empfinde ich die Tempaltesyntax als viel sauberer und "einleuchtender". Aber dies ist nur meine Meinung und ich möchte natürlich keine Diskussion los treten.

11.05.2016 - 11:14 Uhr

Danke. Es hätte ja auch sein können, dass es an mir liegt.

Dann wieder zurück zu SignalR 2.X

11.05.2016 - 10:10 Uhr

Das letzte was ich gestern getestet hatte war mal die Protokolle durchzugehen. Ich kann mich daran erinnern, dass er zum Beispiel beim Longpolliing hier auf die Nase gefallen ist:

https://github.com/SignalR/SignalR/blob/dev/src/Microsoft.AspNet.SignalR.Client45/Http/DefaultHttpClient.cs Zeile 142.



return httpClient.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead, cts.Token)                
                .Then(responseMessage =>
                {
                    if (responseMessage.IsSuccessStatusCode)
                    {
                        responseDisposer.Set(responseMessage);
                    }
                    else
                    {
                      throw new HttpClientException(responseMessage); //Exception
                    }

                    return (IResponse)new HttpResponseMessageWrapper(responseMessage);
                });


Die Url c# <--> javascript sah vollkommen anders aus. Ich nehme mal an aufgrund der Protokoll-Version 1.4 -> 1.5.
Ich gehe jetzt mal nicht davon aus, dass die URL "kaputt" war.

Die eigentliche "Exception" wird dann wahrscheinlich beim Server fliegen

11.05.2016 - 09:22 Uhr

Javascript verwendet Protocol-Version 1.5 und C# 1.4. Aber soweit ich gelesen hatte, war die Änderung nur für Browser relevant.

Hallo Abt. Danke für den Hinweis. Darf ich fragen wo du das gelesen hast? Ich habe leider nichts gefunden diesbezüglich. Gibt es eine alternative zum SignalR Client 2.2.X ? Auch hier finde ich nur die Version 3 vom Server.

10.05.2016 - 21:54 Uhr

Hallo zusammen,

ich habe seit einigen Tagen ein Problem bezüglich SignalR in Version 3. Ich weiß Version 3 ist noch relativ weit weg von einem offiziellem Release, aber vielleicht hat ja jemand schon ein par Erfahrungen gesammelt.

Der Server liegt in Version 3.0.0-rc1-final vor. Der JavaScript Client funktioniert ohne Probleme.
Der C# Client allerdings nur bedingt. Es funktioniert die Anmeldung und der Server kann Methoden beim Client aufrufen, allerdings nicht umgekehrt.

Ich habe eine minimales Beispiel zusammengestellt:


 private static HubConnection _connection;
        private static IHubProxy _serviceGuard;

        static void Main(string[] args)
        {
            _connection = new HubConnection("http://localhost:5000/signalr");
            _serviceGuard = _connection.CreateHubProxy("Test");
            _serviceGuard.Subscribe("Test").Received += Program_Received;
            _connection.Start().ContinueWith((task) =>
            {
                _serviceGuard.Invoke("Test").Wait(); //Hier die Exception
            });

            Console.ReadKey();
        }


 [HubName("Test")]
    public class TestHub : Hub
    {
        public void Test()
        {
            Trace.WriteLine("Test aufgerufen");
        }

        public override Task OnConnected()
        {
            Trace.WriteLine("Login");
            Clients.Caller.Test();
            return base.OnConnected();
        }
    }

Ich bekomme folgende Exception:

Fehlermeldung:
{"StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:\r\n{\r\n Date: Tue, 10 May 2016 19:50:36 GMT\r\n Server: Kestrel\r\n Content-Length: 0\r\n}"}

Serverseitig wurden die "DetailedErrors" aktiviert:


services.AddSignalR(options =>
            {
                options.Hubs.EnableDetailedErrors = true;
            });

Mit dem Error ist leider nichts anzufangen. Hat zufällig jemand bereits den C# Client ans laufen bekommen?

25.04.2016 - 09:23 Uhr

Ich wollte dich mit ninite nicht entmutigen, sondern eine weitere Idee/Vorlage liefern. Selbst wenn am Ende niemand deine Software einsetzt, du wirst auf jeden Fall etwas lernen 👍

23.04.2016 - 15:28 Uhr

Guck dir mal an, wie ninite das Problem löst:

https://ninite.com/

11.04.2016 - 12:51 Uhr

Ja du hast recht. Vielen Dank nochmal für deine hervorragende Hilfe.

Ich werte mir RabbitMQ mal ansehen.

11.04.2016 - 12:44 Uhr

Alles klar. Da mir leider kein Azure zur Verfügung steht: Wie würdest du die Queue implementieren? Auf Basis einer Blocking-Collection wie auf deinem Blog gezeigt? Ich setze diese Logik bereits bei einem Logging-Service ein und hatte bisher ganz gute Erfahrungen damit.

11.04.2016 - 12:11 Uhr

Das heißt dein Pushservice hat eine Queue die abgearbeitet wird? Die Queue hält mehrere Nachrichtenobjekte und die wiederum Ziel-Client, Nachricht usw.

Sämtliche Programme die Nachrichten rausschicken möchten, befüllen die Queue über Rest-Calls mit Nachrichtenobjekten.

Enthält das Nachrichtenobjekt noch eigene Logik? Zum Beispiel:

Interface INachricht mit Methode Send();

App X hat das Nachrichtenobjekt X und eigene Logik zum Versenden. App Y genauso, Client Z reicht das allgemeine Nachrichtenobjekt mit Standard-Logik

Die Queue würde dann über INachricht laufen.

So müsste eine neue Nachricht (mit neuer Funktion) nur im Pushservice implementiert werden.
Oder verstehe ich etwas falsch?

EDIT: Ich glaube das war quatsch. Um verschiedene Nachrichtenobjekte an die RestApi zu senden, bräuchte man entweder ein Custom-Modelbinder oder verschiedene Routen.... Ich warte besser erstmal auf deine Antwort.

11.04.2016 - 11:42 Uhr

Alles klar, vielen Dank. Deine Hilfe war sehr Aufschlussreich 😃

11.04.2016 - 11:30 Uhr

Danke nochmal, dass mit NodeJS war mir nicht bewusst. Ich werde mir das Video natürlich ansehen, werde nur leider erst abends dazu kommen.

Bezüglich dem FilesystemWatcher hatte ich kurz gesucht und folgendes gefunden:

https://stackoverflow.com/questions/33902230/cannot-use-filesystemwatcher-with-coreclr-on-ubuntu

Daher war ich davon ausgegangen, dass es geht.

Das heißt, dein Pushservice sendet die "Nachrichten" von X Programmen über Websockets raus. Die Nachrichten, die verschickt werden, kommen von diesen Programmen zum Beispiel über Rest-Calls rein? So wäre das ganze um beliebig viele Programme erweiterbar.

Clientseitig müsste ich dann nur dafür sorgen, dass die Nachrichten richtig verteilt werden, oder? (Angular-Controller X für Excel, Angular-Index-Controller für Nachrichten vom Typ Y)
Sei es nun eine Angular oder Desktop-Anwendung. (Ich gehe davon aus, dass die Verbindung einmal aufgebaut wird und dann bis zum Logout bestehen bleibt)

Spricht etwas dagegen, die Nachrichten per Broadcast in einer Angular-App an die Controller zu verteilen? Oder ist das zu ineffizient?

11.04.2016 - 11:02 Uhr

Vielen Dank für die ausführliche Antwort. Sehr nachvollziehbar und hilfreich. Ich werde es nun erstmal wie von die beschrieben aufziehen und gucken ob ich auf Hindernisse stoße.

Danke

EDIT: Wenn du von einem "Watcher" redest

eine .NET Core App mit einem Watcher für die Excel Datei für die Verarbeitung

meinst du den FileSystemwatcher? Ich hatte bisher nie die Anforderung diesen zu benutzen, habe allerdings gehört, dass dieser nicht unbedingt zuverlässig sein muss.

11.04.2016 - 09:56 Uhr

Danke erstmal. "Eine" Frage hätte ich aber noch zur Architektur:

Die Web Api übernimmt den Upload und schiebt die Datei in einen Ordner.

Gibt es hier nun 2 weitere Anwendungen oder eine? SignalR für Kommunikation zum Client und Anwendung für den Import? Oder nur die SignalR Anwendung, die auch den Import übernimmt?

Sollte es 2 Anwendungen geben, wäre meine Frage, wie die Anwendungen miteinander "sprechen". Auch wieder SignalR? Da sonst der Client keine Informationen bekommt.

11.04.2016 - 09:37 Uhr

Da das ganze auf Asp.Net Core umziehen soll, wäre Plattformunabhängigkeit ganz schön. Daher würde der Windows-Service rausfallen (auf Mono würde ich gerne verzichten)
Oder einmal ein Windows-Service für Windows und eine Anwendung für Linux (Asp.Net Core-> Konsole?).

Wie würdest du mit dem Windows-Service kommunizieren? Wenn über SignalR Live-Aktualisieren rausgehen sollen, müsste ich diese vom Serivce bekommen. IPC --> WCF?

EDIT: Wie am besten mit der Linux-Anwendung kommunizieren?
komplett auf WebSockets setzen (Linux und Windows)?

Ablauf:

  1. Hochladen über Web Api
  2. Über SignalR zum Backend-Verbinden
  3. dann den Import starten (oder Import über Web Api starten?)
  4. Verbindung trennen

Da SignalR sonst nicht gebraucht wird, würde ich nur dafür die Verbindung öffnen und dann wieder schließen.

SignalR und WebApi in einer Anwendung, mit verschiedenen URL's, oder hier auch nochmal splitten?
(Mir persönlich wäre es ein bisschen viel 3 Anwendungen zu haben, für einen "kleinen" Import.)

Vielen Dank

11.04.2016 - 09:20 Uhr

Hallo zusammen,

ich hätte eine kurze Frage: Die Anforderung ist es, Excel-Dateien in einer Datenbank zu importieren. Das ganze muss von extern funktionieren.

Bisher wurden die Excel-Dateien nur über eine Web Api hochgeladen(In Chunks).

Mich würde interessieren, welcher der x-tausend Wege eurer Meinung nach am besten geeignet wäre:

**Nachdem die Dateien hochgeladen sind, dem Benutzer die Möglichkeit geben den Import anzustoßen (pro Datei anstoßen, oder einmal anstoßen für alle?). Daraus folgt: **

--> Request-Verbindung offen halten und dann einen Statuscode zurückgeben. Wenn einmal anstoßen für alle, müsste man noch entsprechend zurückgeben, welche Datei einen eventuellen Fehler hatte. Außerdem müsste die Timeout-Zeit wahrscheinlich relativ hoch sein.

--> Anstoßen und Ok zurückgeben für Start des Imports(Request-Ende). Intern dann vielleicht in einem Dataflow die Dateien abarbeiten. Nur wie bekommt der Benutzer eine Rückmeldung? Polling und gucken ob abgeschlossen? Wenn ja, wie sollte der Dataflow-Service aufgebaut sein? Als Singleton für alle Benutzer, oder jedes mal eine neue Instanz und entsprechend neue Threads (eher ungünstig für Web Api).

--> SingalR für "Live-Aktualisierung" des Imports. Bisher wird SignalR aber in der Web Api nicht gebraucht. Live-Aktualisierung beim Client ist kein muss.

Oder auf den Chunk-Upload verzichten?

--> Dann direkt den Import nach Upload starten.

Ich hoffe ihr könnt meinen Gedankengängen folgen und mir den richtigen Weg zeigen.

Danke