Haben es jetzt so gelöst, dass das generierte Soap in etwa dem entspricht, was Asmx-Webservices auch generieren, durch Verwendung von MessageContracts.
Ist zwar ein wenig Klassen-OVerhead im Dienst, dafür bleibt die Client-Anbindung einfach.
für normale Webservices ("Service.asmx") nutzen wir einen Authentifizierungsmechanismus mit einem "ServiceAuthenticationHeader". Für ein aktuelles Projekt brauchen wir dies auch für WCF Services.
Das wichtige ist, dass der SoapHeader genauso aussehen soll wie beim normalen Webservice.
Das funktioniert soweit, wenn ich im Client den ServiceAuthHeader noch mal bekannt mache und als MessageContract bekannt gebe. Dann kann ich den Header mit Hilfe von folgendem hinzufügen:
using (ServiceClient client = new ServiceClient())
{
using (OperationContext ctx = new OperationContext(client.InnerChannel))
{
ServiceAuthHeader header = this.GetAuthHeader();
System.ServiceModel.Channels.MessageHeader authHeader = System.ServiceModel.Channels.MessageHeader.CreateHeader("ServiceAuthHeader", string.Empty, header);
System.ServiceModel.OperationContext.Current.OutgoingMessageHeaders.Add(authHeader);
// execute service call
// ...
}
}
Das unschöne daran ist, dass der Aufrufer die ServiceAuthHeader-Klasse quasi selbst noch einmal entwickeln muss mit den entsprechenden Eigenschaften. Gibt es hier einen Weg, wo svcutil den Header schon im Client-Proxy mit generiert?
Bei dem ganzen handelt es sich um eine Schnittstelle für einen externen Dienstleister. - Daher wollen wir es diesem nun auch nicht unnötig schwer machen den AuthHeader abzubilden.
Bei einfachen Webservices reicht es in der Service.asmx.cs den ServiceAuthHeader als Property hinzuzufügen.
das hatte ich auch schon gefunden. Allerdings ist das Diif Ergebnis dort jetzt nicht wirklich brauchbar bzw. sehr komplex.
Bei Unterschieden in den Werten gibt er nur die Indizes der Knoten aus, die sich geändert haben und den neuen Wert.
Habe nun basierend auf Palladin007's Vorschlag eine aktuell gut funktionierende Lösung gefunden.
Für ein aktuelles Projekt muss ich ein Xml-File mit seinem Vorgänger vergleichen und alle Änderungen zusammenfassen.
Dabei sollen teilweise Xml-Knoten beim Vergleich ausgeschlossen werden.
Im Ergebnis sollen anschließend n-Xml Dateien raus kommen, die jeweils den geänderten Knoten und den alten sowie neuen Wert und alle ignorierten Werte enthält.
Bei dem flachen Xml kein Problem. Das wird straight forward runterprogrammiert und die Xml Knotenweise durchgegangen. Die Knoten aus der alten Xml werden dann mithilfe des NodeNamen aus der neuen gelesen.
Allerdings habe ich einen Knoten im Kopf, wie ich das bei Xml-Dateien bewerkstellige, die eben nicht flach alle Informationen auf einer Ebene haben. Hat hier jemand eine Idee bzw. einen Vorschlag?
Aber meiner Erfahrung nach hat DataBinding auch so seine Tücken in MultiThreaded Szenarien.
Ich scheitere z.B. trotz Jahrelanger Erfahrung in der Entwicklung immer noch daran, in Windows Forms eine vernünftige Synchronisierung hinzubekommen. Denn nur davon, dass ich meine BindingList oder ähnliches ans Grid pappe kann ich trotzdem nicht einfach in einem anderen Thread Einträge bearbeiten, entfernen und hinzufügen ohne das mir eine entsprechende Exception um die Ohren fliegt.
Noch mal zu den Board und Thread Status. Es gibt ja den Link "Forenbereich als gelesen markieren.". Der funktioniert auch erst mal soweit. Alle ungelesenen Themen werden als gelesen markiert. - Auch das Board selbst bekommt den gelesen Status.
Allerdings habe ich gestern erst einmal alle auf gelesen gesetzt. Heute sind diese wieder als ungelesen markiert. Hat das noch jemand oder liegt das an mir?
Kennst du denn die groben Bytepositionen? Dann würde ich das File einlesen und dann die entsprechenden Bytes auslesen.
Andernfalls wird es schon schwieriger, wenn du tatsächlich über bestimmte Inhaltsmuster gehen musst.
Huh, sehe grade das scheint ein Bug in VS zu sein. Hab einfach mal versucht ein geerbtes Formular zu erstellen. Und siehe da. Gleicher Fehler (hier: VS Professional 2017).
Ich empfehle dir ohnehin: Verweise auf die Bibliothek mit dem BaseForm, erstelle ein neues Formular und ändere den Basistyp von Form auf dein BaseForm.
Im .NET Umfeld empfehle ich den Oracle.ManagedDataAccess aus den Oracle-Komponenten. Ein großer Vorteil bei diesem ist nämlich dass bei richtiger Verwendung gar keine Oracle Client Installation auf dem Zielsystem erforderlich ist.
Denn die korrekte Installation des Oracle Clients ist auch immer so eine Sache. Vor allem, wenn man den x86 und den x64 Client benötigt.
Hast es denn mal auf einem Windows Rechner probiert?
Finde leider auch nur Beiträge, wo Leute nach dem Update auf Version 2 der Microsoft Datenprovider Fehler hatten. - Möglicherweise liegts daran? Hast du mal eine ältere Version des Packages probiert?
@inflames2k, in der Konsolenapplikation ohne Service gibt es doch noch gar keinen DataProcessor.
Nun, wenn du deinen eigenen Code nicht liest. Dann verstehe ich die Wurzel der Probleme.
Zitat von TomRie
Dass der Service "und nur der Service (inkl. DataProzessor)" nicht für diese Art Anwendung geeignet ist sage ich ja schon lange, daher muss ja etwas anderes her.
Ja genau. - Nämlich die korrekte Variante ohne Timer. - Was passiert denn wenn du deinen DataProcessor direkt ausführst statt über den Timer? - Dort sollte man ansetzen den Fehler zu suchen und nicht irgendetwas Wild mit Timern dahinter zu Frickeln damit überhaupt was startet.
Zitat von TomRie
Übrigens wenn das gezeigte nur als Konsole ausgeführt wird, kommt der Timer entgegen deiner Ansicht gar nicht zum Zug, nur beim auführen des Services. Das erkennt man kurzerhand im Beispiel über den Link.
Das habe ich auch nie behauptet. - Im Gegenteil. Ich habe dich drauf hingewiesen, dass er ja dort - wo dein Programm funktioniert - eben nicht zum Einsatz kommt.
Nun weiß ich auch, wo das ganze Problem her kommt. - Du schreibst leider nur ab, was in der Anleitung vorgegeben ist ohne dir weitere Gedanken darüber zu machen. Für den in der Anleitung verwendeten Anwendungsfall [der auch nur ein Beispiel ist] macht der Timer natürlich sinn. - Für deinen Fall aber nicht. - Also als erstes Weg mit dem Timer. Danach können wir uns der weiteren Probleme annehmen.
Dein Problem hat nichts. Aber auch gar nichts mit Diensten an sich zu tun. Wenn du das in der Service-Klasse gezeigte in einer Konsole ausführst, wirst du auf genau die gleichen Probleme stoßen.
Der riesen Unterschied den du eben fabriziert hast ist:
deine Konsole initialisiert den DataProcessor und führt ihn aus
dein Dienst initialisiert alle 10 Sekunden einen DataProcessor und führt ihn aus
Wenn du jetzt noch verstehst, was ich versuche dir zu sagen, solltest du der Lösung für dein Problem schon näher kommen.
Wenn es bei Ausführung ohne den Timer zu Fehlern kommt, dann poste diesen doch mal. - Aber der Timer macht ohnehin wie schon von anderer Stelle angemerkt keinen Sinn.
Hat der User überhaupt Zugriff auf die master Datenbank? Versuche doch doch mal mit diesem User per SQL Server Management Studio anzumelden und prfüe ob du Zugriff auf die master Datenbank hast.
Übrigens sollten Systemdatenbanken tabu sein es gibt eigentlich keinen Grund darauf direkt zuzugreifen.
Auch wenn deine Einwände korrekt sind gehe ich immer noch davon aus, dass derartige Sachen nicht zu dem genannten Fehler führen.
Für fehlende Berechtigungen auf eine bestimmte Datenbank wird der SQL-Server und die Client-Bibliothek andere Exceptions. Beispielsweise:
Fehler
cannot open database masterrequested by the login. the login failed
Nach der Beschreibung macht deine MessageReceiverService -Klasse speziell mit dem Timer noch weniger Sinn.
Du erzeugst alle 10 Sekunden einen neuen DataProcessor mit der darunter liegenden Logik. - Wenn ich ins blaue raten sollte knallt dir die Laufzeit dann beim 2. Start deiner Server-Methode die Exception raus, da der Port bereits verwendet wird.
Im Allgemeinen wäre es wohl besser einen Listener-Thread zu verwenden und nicht zyklisch neu den Listener aufzubauen.
Was du im Code machst ist:
1) Server Port öffnen
2) Auf Verbindung warten
3) Kommunikation mit Client
Solang dieser Ablauf jetzt durch rennt, hast du das Problem, dass alle 10 Sekunden ein neuer Listener erstellt werden soll und das ganze noch mal starten soll. Du kannst aber nur einmal auf den Port horchen.
Geschickter wäre es also mit den Asynchronen-Methoden der Netzwerkklassen zu arbeiten und genau eine Listener Instanz zu verwenden.
ersetze mal Database=master mit Initial Catalog=master.
Das sollte normalerweise zu einem anderen Fehler führen. Der Fehler den Platoon da beschreibt tritt dann doch eher schon beim Verbindungsaufbau zur Instanz auf.
Mögliche mir bekannte Ursachen wären:
Datenbankserver ist vom PC auf dem die Anwendung läuft nicht erreichbar [möglicherweise anderes Netzwerk]
Portfreigaben fehlen
Instanzname ist fehlerhaft
Die zu verwendende Datenbank wird ja ohnehin erst im nächsten Schritt verwendet, wenn eine Verbindung grundsätzlich schon mal zustande kam.
Am Ende, wenn es nur für dich bestimmt ist, musst du entscheiden was sinnvoll ist und was nicht.
Von der Beschreibung her, baust du ziemlich viel bereits vorhandene Funktionalität des Frameworks einfach nach. Ob das so gut ist, wage ich zu bezweifeln.
Aber ohne genaue Kenntnis, warum du genau den Weg gehst kann man dir auch schwer Empfehlungen geben.
Hatte das Frame / die Frames der Optik wegen genommen, weil es den Teil etwas abgegrenzt hat. So ists natürlich auch OK.
Ist eigentlich etwas geplant, dass zumindest im Projekte und Snippet Board der Eingangsbeitrag vom Nutzer geändert werden darf? Ich mein normal sollten es ja Power User ohne hin dürfen. - Aber dort posten ja nicht nur Power User.
Aber durch Änderungen des BB-Code Parsers werden einige Sachen nicht mehr korrekt dargestellt. [Das ist vernachlässigbar]
Allerdings zählen dazu auch Verlinkungen die weggefallen sind. Siehe PS Fritz!Box API - TR-064 Schnittstelle. Da ich den Eingangsbeitrag nun auch aktuell nicht ändern kann, bliebe mir nur der Weg am Ende einen neuen Beitrag mit den Verlinkungen anzufügen.
ich war jetzt natürlich davon ausgegangen, dass im Beispiel keine Datenbank beteiligt ist. Bei Datenbankbeteiligung würde ich dann eher zu den Standard DB-Mechanismen für ID's raten.
Nun, dann wäre wohl das einfachste den letzten Eintrag zu lesen die Kunden-/Produktnummer auszulesen und anschließend mit Zähler +1 dem neuen Kunden zuzuweisen.
Sind es tatsächlich Listen dann ist der Zugriff doch auch recht einfach.
Nun gab es eine Erweiterung der Services und auch einen neuen. Installiert werden soll vorerst nur der neue. Da alle Services die gleichen Assemblies nutzen, würde die Installation bedeuten, dass die Anwendungen die auf die bestehenden Services zugreifen z.T. Probleme kriegen.
Nun war der Gedanke dahin eine Parallel-Installation für den neuen Service durchzuführen und später alles wieder in einem Ordner zu vereinen. Allerdings müssten dann alle Clients wieder angepasst werden.
Gibt es über den IIS oder ähnliches einen Weg, den neuen Service im Pfad
D:\Webservices\ERP_Temp\Service8.asmx
zu installieren, und dennoch über den Hauptpfad und somit die Haupturl zuzugreifen?
Verstehe ich das richtig, dass Code-Block "A" bzw. "B" in den Methoden 1 und 2 identisch vorhanden ist, allerdings eben dupliziert, was du vermeiden willst?
Ein bisschen viel Spekulation. Das entnehme ich dem Eingangsbeitrag so nicht.
@derrobin
Wie Abt schon geschrieben hat, kannst du die gleichen Parameter auch noch an 100 weitere Methoden übergeben, wenn diese darin benötigt / ver- / bearbeitet werden.
Erkläre doch mal genauer was du vor hast und warum du denkst die Parameterübergabe irgendwie einkürzen zu müssen.
Ansonsten: Du musst im ersten Schritt die Kaffeesorten ja nicht in einer Datenbank speichern. Du kannst sie auch erst mal im Code festlegen und später die Datenquelle anpassen.
Im Heise Artikel dazu hieß es auch, Linux sei nicht implementiert, man überlasse das der Community.
Das bedeutet aber nicht, das Linux nicht unterstützt wäre sondern dass eben die Plattformspezifische .NET MAUI Implementierung nicht von M$ sondern von der Linux Community geliefert werden.