Danke an alle. Ich habe das jetzt über FileStreamResult, wie david.m im zweiten Link erwähnt hat, gelöst.
P.S.
Natürlich gibt es Prüfungen bezüglich Berechtigungen, ob das File überhaupt existiert usw. Diese habe ich aber nicht mit angegeben, da sie ja für die Frage nicht relavant sind.
Ich habe eine ASP.NET Core Web-API die ich auf Version 6 umstellen soll. In dieser ist in einem Controller folgende Methode:
[HttpGet]
public async Task<IActionResult> GetDocument(string datei)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
try
{
WebClient client = new();
client.Credentials = CredentialCache.DefaultNetworkCredentials;
Task<byte[]> t = client.DownloadDataTaskAsync(new Uri(datei));
await t;
var file = t.Result;
return File(
file,
new ContentTypes().GetContentType(datei),
"_File" + Path.GetExtension(datei).ToLowerInvariant());
}
catch (Exception ex)
{
return BadRequest(ex.GetAll());
}
}
Der String für die Datei sieht wie folgt aus:
\\Server\Share\Directory\Filename
Jetzt meldet mir das System. dass "WebClient" deprecated ist und ich "HttpClient" statt dessen verwenden soll.
Nur erlaubt mir dieser nicht, eine Uri im Format "file://...." zu verwenden. Auch meine Recherche im Internet
hat mir keine Erkentniss darüber gebracht, wie ich dieses Problem lösen kann. Vielleicht habe ich nach den falschen Stichwörtern gesucht.
Kann mir vielleicht einer von Euch hierzu einen Tipp geben?
Ich habe den Link eigentlich deshalb gepostet, vielleicht kannst Du hier Dir etwas abschauen, wie da die Berechnung gemacht wird, ob der Text gekürzt werden muss oder nicht. Daraus müsste sich doch dann ergeben, ob der Text ins Feld passt oder nicht.
Ich habe mal bei einem WPF-Projekt eine TextBox eingesetzt, die bei zu langem Text diesen abschneidet und durch "..." ersetzt. Dieses ist auf CodeProject zu finden. Vielleicht hilft Dir das ja.
Der Fehler würde auch mit SQL-Parameter passieren (beachte die Werte in der Combobox). So wie es jetzt aufgebaut ist, bekommt der TE nie Werte aus der DB.
Was Dir bis jetzt noch keiner gesagt hat: setze beim Vergleich nach dem Select-Command mal einen Breakpoint und schau Dir im Debugger Deinen Command an. Dann wirst Du den Fehler selbst bemerken.
Wenn Du auf "Form1.cs" doppelt klickst, dann öffnet sich entweder der Designer oder die "Code-Behind-Datei". Dies kannst Du einstellen, in dem Du mit der rechten Maustaste das Kontextmenü öffnest und dann die Option "Open with" auswählst. Danach kannst Du die Standardaktion festlegen. Du kannst im Kontextmenü auch direkt den Code oder den Designer öffnen.
Ich hatte einmal ein ähnliches Problem. Es gibt von DevExpress eine Komponente namens "Spreadsheet". Diese kann Excelfiles direkt einlesen (mit allen Formeln, benannten Felder usw.) und funktioniert genauso wie Excel. Man kann sogar eine Oberfläche dazu erstellen, die wie Excel aussieht. Über C# kannst Du dann die Felder auslesen, die Berechnungen starten und was Du sonst noch alles brauchst.
Postman --> Post mit Modell im Body --> ASP.NET Core --> gRPC --> Windowsservice
Das ganze funktionierte bis jetzt alles tadellos und ich bekomme die richtige Antwort mit dem Status 200 zurück. Jetzt habe ich das Modell um einen Wert erweitert und die Middleware und das Service entsprechend erweitert. Bei mir in der Debugumgebung läuft alles so wie es soll. Jetzt habe ich das ganze in unsere Testumgebung deployed und wollte das mit Postman testen. Wenn ich jetzt den POST-Request absetze, dann kommt immer einen Error 404 (not Found) zurück. Wie kann ich herausfinden, wo der Fehler liegt?
P.S.
Andere Requests laufen einwandfrei, es liegt also nur an dem einen Request.
das Netzwerkprotokoll habe ich mir angesehen. Leider sieht man daraus nicht viel, da der Client natürlich immer dasselbe sendet. Wenn ich die Application im Commandfenster laufen lasse, dann kommt halt nach einigen Millisekunden die richtige Antwort, beim Service nach einigen Minuten der Reply mit HTTPResponse 200 und gRPCStatus 1. Dazwischen liegt das Service, das halt nichts macht.
Ich habe aber gestern noch einiges im Internet recheriert und bin dabei auf das Topshelf-Projekt (Topshelf) gestossen. Damit habe ich den Server neu aufgesetzt und jetzt funktioniert alles (Kommunikation über TCP für die alten WindowsClients und über gRPC für die Web-Applikation).
Ich möchte aus einer .ASP NET-Core Application auf ein bestehendes Service (.Net FW 4.6.1) zugreifen. Ich habe mich hier für die Kommunikation mittels gRPC entschieden. Mein Server sieht wie folgt aus:
string IP = "0.0.0.0";
int Port = 23116;
try
{
Server server = new Server
{
Services =
{
GRPC_Test.BindService(new Test_GRPC())
},
Ports = { new ServerPort(IP, Port, ServerCredentials.Insecure) }
};
server.Start();
service.EventLog.WriteEntry($"API-Server auf {IP}:{Port} gestartet");
}
catch (Exception ex)
{
service.EventLog.WriteEntry("API-Server konnte nicht gestartet werden");
service.EventLog.WriteEntry(ex.Message);
}
und der Client so:
int Port = 23116;
//string IP = "127.0.0.1"; // localhost
string IP = "10.xx.xx.xx"; // Server-IP
Channel channel = new Channel(IP, Port, ChannelCredentials.Insecure);
var client = new GRPC_Test.GRPC_TestClient(channel);
Wenn ich das ganze im Visualstudio (mit der lokalen IP im Client) laufen lasse, dann funktioniert alles wunderbar (HTTP-Request via Postman liefert richtigen Reply). Kopiere ich die EXE auf den Server, starte diese in einem CMD-Fenster und lasse den Client in VS laufen, dann funktioniert es auch wie es soll. Installiere ich die EXE aber am Server als Service, dann bekomme ich im Client nach einiger Zeit eine Exception mit folgendem Inhalt:
und der Stacktrace zeigt auf die aufrufende Funktion. Leider konnte ich auch nichts über Google hierzu finden, daher hier meine Bitte um Hilfe. Vielleicht wissen ja die Gurus unter Euch, wo der Fehler verborgen ist.
stell Deine Befehle die Du senden möchtest (Timer, User) in eine Queue und arbeite diese sequentiell ab. Und zwar immer erst dann, wenn eine Antwort vollständig empfangen wurde. Ich vermute mal, dass Deine Peripherie durcheinander kommt, wenn es beim Senden eine neue Nachricht bekommt.
Du kannst über "Help/Add and Remove Help Content" im Help Viewer die Hilfen auswählen und downloaden (Manage Content). Danach im Visual Studio als Help-Viewer über "Help/Set Help Preference" "Launch in Help Viewer" auswählen.
Es geht mir nicht darum, die ganze bestehende Applikation/Infrastruktur umzustellen, sondern nur neue Plugins in die neue Welt zu bringen. Da das ganze nur bei uns im Haus läuft (internes LAN, hinter einer DMZ) wäre das Problem mit der Authentifizierung meiner Meinung nach nicht gegeben (oder sehe ich das falsch?).
Das ganze ist deshalb noch so allgemein, da ich erst mal die Möglichkeiten abklären möchte. Dies damit ich dann entsprechende Schulungen (ohne die es wohl nicht gehen wird) beantragen kann. Wenn ich aber meinem Chef sage "ich muss jetzt alles aus den letzten 12 Jahren umstellen" dann wird die Antwort wohl "Das kannst Du vergessen" lauten.
Guten Morgen
Ich bräuchte mal Eure Anregungen und Meinungen. Ich habe eine Client-Server-Anwendung welche seit ca. 12 Jahren von mir entwickelt und auch noch immer aktuell weiterentwickelt wird. Diese hat folgenden Aufbau:
1. Server : Windows-Service mit Verbindung zu SQL-,Oracle- und Progress-Datenbanken. Nimmt die Aufrufe der Clients entgegen, verarbeitet diese und sendet via TCP einfache Typen (int,string…) oder eine DataTable zurück.
2. Client : Eine Anwendung welche auf einem Netzlaufwerk liegt und mittels TreeView den Usern die Module anzeigt, für die sie über das AD berechtigt sind. Diese Module (derzeit ca. 85) werden dann als Plugins in eine eigene App-Domaine geladen und ausgeführt. Dadurch kann jederzeit ein Update der Plugins gemacht werden.
Diese Struktur läuft einwandfrei mit WinForms. Jetzt habe ich für die letzte Anwendung bereits den Pfad etwas verlassen, in dem ich für eine andere Anwendung eine Middleware in WPF geschrieben habe, die aber auch auf den Serverdienst zugreift.
Nachdem ja jetzt sehr viel von Web-Anwendungen (Angular, Typescript etc.) die Rede ist würde ich auch gerne auf diese Technologie umsteigen. Die Gelegenheit würde sich demnächst anbieten, da ein neues Projekt (= Plugin) ansteht.
Jetzt meine Frage an Euch: kann ich die bestehende Infrastruktur so weiter verwenden oder müsste ich das ganze neu auf die Beine stellen. Ich stelle mir das ungefähr so vor, dass ich aus der Clientanwendung die Angular-App aufrufe und diese via Web-API Verbindung zu meinem Windowsdienst aufnimmt. Oder seid ihr der Meinung „Schuster bleib bei deinen Leisten“ und ich sollte weiter mit WinForms arbeiten.
select distinct
ProjektID
,Datum3 = (select a.Datum from Test a WHERE a.Status = 3)
,Datum5 = (select b.Datum from Test b WHERE b.Status = 5)
from Test
dann solltest Du eine Tabelle mit den gewünschten Spalten bekommen.
Thomas
P.S.
Ich habe gerade festgestellt, dass obige Lösung nicht richtig funktioniert, sorry. Die Auswertung von hypersurf liefert Dir fast die richtige Lösung, es fehlt nur ein DISTINCT im Select.
Ich bräuchte mal einen Denkanstoß. Ich habe eine WPF-Applikation die jetzt mit einer Fremdapplikation via einer API-DLL angesprochen werden soll. Es sollen Daten in meine Applikation übergeben, dort verarbeitet und das Ergebnis wieder zurück geliefert werden. Ich habe jetzt probiert, über WCF aus der API-DLL mit meiner Anwendung zu kommunizieren (diese ist dann der WCF-Host). Hier habe ich aber zwei Probleme :
1. Wenn meine Anwendung nicht gestartet ist funktioniert das natürlich nicht. Die Anwendung kann ich natürlich über einen Prozess starten, aber wie teile ich dann der API-DLL mit, das der Host bereit ist?
2. Wenn die Anwendung läuft, funktioniert die Kommunikation erst mal. Schließe ich die Fremdanwendung aber und starte sie neu, dann kommt in meiner Anwendung nichts mehr an.
Ist hier WCF überhaupt das richtige Mittel oder würdet Ihr das anders lösen? Wenn WCF richtig ist, dann kann ich ja relevante Teile hier posten und auf Eure Hilfe bezüglich der Probleme hoffen.
Ich verstehe den Sinn nicht ganz. Wenn Du einen USB<->Seriell-Adapter an das System anschließt, dann wird diesem ein COM-Port zugewiesen. Dieser ist im Gerätemanager zu sehen. Dann startest Du ganz normal Dein altes DOS-Programm und konfigurierst dort den USB-COM-Port und fertig. Ein Problem hast Du nur, wenn dein Programm nur bestimmte COM-Ports zulässt. Dann musst Du den Port im Gerätemanager entsprechend um konfigurieren.
Ich hatte vor Jahren so ein ähnliches Problem, damals mit Delphi 1.0 (Pascal). Ich habe es damals so gelöst, das ich eine Checksumme über die Datei gebildet und diese vor dem Laden überprüft habe. Hatte der Benutzer etwas im File geändert, stimmt diese natürlich nicht mehr und das Laden wurde abgebrochen.
1. Kopiere die EXE-Datei auf den Desktop
2. Hefte das Programm an die Taskleiste
3. Mittels rechter Maustaste die Eigenschaften der Verknüpfung bearbeiten
4. Bei "Ziel" und "Ausführen in" den Netzwerkpfad eintragen
5. Das Programm kann dann aus der Taskleiste verwendet werden
6. Das kopierte Programm am Desktop kann wieder gelöscht werden.