Laden...

Forenbeiträge von Taipi88 Ingesamt 1.029 Beiträge

19.11.2020 - 06:56 Uhr

Hi,

ich fürchte damit wirst du nicht sonderlich weit kommen ohne eine Sage-Instanz.

Grundlegend haben die mehrere API's mit Doku - ohne Instanz kannst du jedoch maximal schauen.

Kannst ja mal durchschauen, ob du was nützliches findest:
https://help.sagecrm.com/on_premise/en/2018R1/dev/Content/Developer/APIs.htm

LG

18.11.2020 - 07:29 Uhr

Hi,

kann nachvollziehen, dass es keinen Spaß macht x-beliebige Schüler zu zwingen ein MS-Konto anzulegen bzw. auch nur durch die Erstellung eines solchen zu schubsen.

On Top:
So wie ich mich an die Schule erinnere haben die Schüler auch keine Benutzerkonten auf den Rechnern - ergo - stehen die Chancen hoch, dass die Schule unwissentlich an der Verletzung von Lizenzvereinbarungen teilnimmt - schlicht weil ein Schüler eingeloggt blieb - ein anderer aber das Konto verwendet - sofern man nun Visual Studio in welcher Form auch immer nutzt.
(Würde mir als Schüler auch nicht passen, dass ich meine Benutzerdaten auf einem Gerät/Konto hinterlasse, über dass ich im Prinzip keinerlei Kontrolle habe)

Grundlegend:
SharpDevelop ist der Vorgänger von MonoDevelop - hier könnte man ggf. noch evaluieren - grundlegend liegt der Fokus hier aber auf VS Code, dass ebenfalls kein Benutzerkonto benötigt.

WebServices auf Basis von ASP.NET Core kann man damit komfortabel schreiben.
Die Microsoft-Beispiele nutzen zwar in der Tat meist Visual Studio - allerdings lässt sich das Endergebnis genauso gut mit VS Code gestalten. Sicher - hier ist in Teilen die cli beteiligt für entsprechende Vorlagen - auf der anderen Seite: "dotnet new webapi" einzugeben sollte im Informatikunterricht ja kein Problem darstellen.

Was VS im Standard vll noch anders macht: Die haben im Standard eine IIS-Express-Integration - allerdings finde ich das seit ASP.NET Core vollkommen unnötig - zum Entwickeln ist "dotnet run" bzw. "dotnet watch" viel angenehmer - mir persönlich gefällt das separate CLI-Fenster mit den Logausgaben.

Wie man dotnet watch einsetzt - kannst du dir z.B. auf folgendem Link anschauen:
https://stackoverflow.com/questions/59830506/hot-to-setup-an-auto-dotnet-watch-run-for-net-core-3-1-projects-using-visual-st

LG

16.11.2020 - 15:59 Uhr

Hi,

da dein VS offensichtlich auf Deutsch ist:
Ich behaupte du suchst den Projektmappen-Explorer (siehe: dein erstes Suchergebnis)

LG

12.11.2020 - 15:13 Uhr

Hi,

naja - ein Shell-Aufruf startet im Endeffekt eine Art Kommandozeile für ein anderes Programm.

Wenn das Python-Programm einen entsprechenden CLI-Aufruf schafft - dann schafft das auch ein Shell-Aufruf.

Wenn das Ganze sich allerdings nur über die GUI anstoßen lässt - wird das mit der Shell nichts.

Um allerdings ehrlich zu sein: Das klingt nicht nach einer Aufgabe aus dem Studium - sondern eher nach einem Nebenjob mit lausiger Aufgabenstellung... Falls nicht würde ich eher erwarten, dass man dich auffordert alles in C# zu implementieren. Dann allerdings CAD in's Spiel zu bringen...

LG

12.11.2020 - 14:30 Uhr

Hi,

was für einen Impor? In C# nimmt man using 😕

Naja - grundlegend hast du mindestens 2 Möglichkeiten soweit ich mit einer schnellen Suche fnde:
a) Einfach per Shell ausführen (halte ich nicht unbedingt für verkehrt)
b) IronPython verwende - aber normal kommt da denke ich kein import (zumindest im C# vor)

Schaust dir vll mal am besten folgenden Thread an:
https://stackoverflow.com/questions/11779143/how-do-i-run-a-python-script-from-c

LG

PS: Wenn man dich zwingt ein externes Script auszuführen - würde ich persönlich wenn ich keine Rückmeldung für mein Programm brauche - immer per Shell bzw. Cmd ausführen. Ist schlicht sehr simpel auf diese Art.

10.11.2020 - 14:05 Uhr

Hi,

soweit für mich ersichtlich ist das zwar möglich - imho aber sehr unschön.
(siehe https://stackoverflow.com/questions/3632422/how-to-change-location-of-app-config)
-> Die Anwendung für sowas neu zu starten klingt für mich nicht nach einer Lösung

Bist du wirklich auf die app.config angewiesen?

Prinzipiell gibt es mit dem aktuellen Konfigurationssystem (siehe https://docs.microsoft.com/de-de/archive/msdn-magazine/2016/february/essential-net-configuration-in-net-core) auf JSON- oder XML-Basis mit Zusatzpfaden wäre das imho ein Leichtes ohne derartige Hacks.

Alternativ musst du ja nicht mal das Konfig-System benutzen. Es genügt doch eine zentral gepflegte XML-Datei, welche per Deserialisierung ausgelesen wird - oder?

LG

03.11.2020 - 11:43 Uhr

Hi,

platt formuliert: Du brauchst einen WebServer, der (was auch immer du genau gemacht hast) ausführen kann - zusätzlich zur Datenbank, welche du ja offensichtlich verwendest...

Grundlegend brauchst du somit einen Server (Linux oder Windows) auf dem du Datenbank und Anwendung installieren und einrichten kannst, im Normalfall eine fixe IP sowie eine Domain.

Wie und was genau du brauchst hängt grundlegend davon ab was du so drauf hast, wie viel Geld du ausgeben kannst/möchtest - und was du eben so alles in deinem Programm verwendet hast. (Gibt hier schlicht zig Möglichkeiten zum Ziel)

Persönlich:
Für einige meiner Anwendungen betreibe ich einen gemieteten Windows-WebServer von HostEurope - dieser Server führt IIS sowie eine Instanz eines MSSQL-Servers aus. IIS wiederum ist letztendlich der Proxy-Server für verschiedene ASP.NET Core - Anwendungen, welche ggf. wieder mit der Datenbank kommunizieren.

Andere meiner Anwendungen (auch ASP.NET Core) laufen hinter NGINX (Webserver als Proxy) direkt auf einem Ubuntu-Server, noch andere Anwendungen sind hinter Traefik (Webserver als Proxy) in verschiedenen Docker-Containern.

Github oder ein FTP-Server genügen jedenfalls für sowas nicht nicht.

Wobei es in Github durchaus möglich ist via CI/CD eine Anbindung zu Azure zum Hosting in der Cloud aufzubauen. Persönlich würde ich dir allerdings vorerst davon abraten - einfach damit du siehst, wie's eigentlich funktioniert...

LG

21.10.2020 - 13:03 Uhr

Hi,

grundlegend: nein - die IDE ist keine Konsole und bietet soweit mir bekannt ist auch nicht die Möglichkeit eine solche inline anzuzeigen - das heißt das Fenster wird sich auf diese Art immer öffnen.
Grundlegend sind im nachfolgenden Link einige Optionen aufgezeigt:
Having the output of a console application in Visual Studio instead of the console

Kurzum:
Wenn du keine Konsolenausgabe möchtest - wäre es am besten eine Windows-(Forms)-Anwendung zu erstellen und dort eben Debug.Write(Line) zu benutzen - dann öffnet sich auch kein Fenster.

Was Logging angeht:
VS selbst hat nichts mit dem Logging in deinem Programm zu tun. Hierzu gibt es allerdings diverse Frameworks - ich denke die bekanntesten sind Log4Net und Serilog. (siehe hierzu jeweils github und nuget)

Was git angeht - git ist weder an Java noch .NET (noch eine bestimmte IDE gebunden) - verwendbar ist es demnach definitiv. VS bietet hierzu teils auch integrierte Funktionen. Ich selbst arbeite meist allerdings lieber mit SourceTree.

LG

20.10.2020 - 09:36 Uhr

Hi,

ohne deinen Code zu kennen kann man dir nicht wirklich helfen.

Unabhängig davon:
Wenn man die Seite liest bekommt man mit dem folgenden Link eine lauffähige Anwendung, welche das deinerseits geschilderte Problem nicht hat. siehe:
https://github.com/ourcodeworld/csharp-scanner-wia

Der dort verwendete Code sieht prinzipiell recht übersichtlich aus wenn du mich fragst.

Kann somit nur empfehlen, dass du das mit deinem Code vergleichst...

LG

20.10.2020 - 08:09 Uhr

Das Semikolon sorgt dafür, dass folgendes ausgeführt wird, wenn "True": Nichts.
Und darauf folgt, dass jede (numerische) Eingabe die Schleife beendet.

Urgh - hast Recht - hatte das Semikolon bei meinem ersten Test direkt gestrichen, weil's nicht hingehört und beim zweiten Test direkt eine höhere Zahl eingegeben. (Hab so nen Fehler noch nie gesehen)

20.10.2020 - 07:02 Uhr

Hi,

grundlegend hilft es (wenn du Hilfe haben möchtest), wenn du beschreibst welches Problem du überhaupt hast.

Direkt offensichtlich:
Da ist ein Semikolon, welches dort nicht hingehört bei: "if (Bid > maxBid);"
(Das hindert das Programm allerdings nicht - es ist nur unnötig)

Bei Ausführung des Codes lässt sich meinerseits feststellen, dass dieser sich verhält wie zu erwarten - nämlich:

Solange die Eingabe < erste Eingabe ist hängt man in der while-Schleife. Gibt man was größeres ein - ist das Programm zu Ende. (Es schreibt sogar "Sold:<Number>" - das Programm ist dann nur so schnell zu, dass du es nicht mehr siehst...)

Sofern das dein Problem ist bin ich sicher, dass du eine Methode aus dem System.Console-Bereich findest, die es dem Nutzer ermöglicht zu sehen was passiert.

LG

13.10.2020 - 09:05 Uhr

Achso - das kannst du dir doch von ASP.NET Core abspicken.

In deiner späteren Anwendung (abseits der Library) wirst du ja sicher etwas ähnliches haben wie die Startup-Klasse - nur dass du es dort wahrscheinlich übersichtlich/einfach halten willst. (Zumindest für Standard-Konfigurationen)

Hab das auch für einige (zugegeben ASP.NET Core basierte) libs gemacht. Schreibst dir einfach einer Helper-Klasse, die solche Services und deren Abhängigkeiten in Standardkonfiguration in der DI einträgt. So sind die einzelnen Komponenten nach wie vor unabhängig und die Verwendung wird trotzdem nicht unübersichtlich, solange der Standard genügt.

Als simple Beispielklasse dafür:


namespace Microsoft.Extensions.DependencyInjection
{
public static class YourNameHereConfigurationExtension
{
public static IServiceCollection ConfigureYourNameName(this IServiceCollectionb services)
{
// your di-registrations here....
}
}
}

Durch eine solche Klasse hast du keine Nachteile - und sogar Microsoft hat's vorgemacht.
(ConfigureMVC, ConfigureLogging, etc.)

Abseits dieser Helfer-Klasse allerdings - ist jegliche Verwendung von DI (oder sogar ServiceLocator) ein Fehler, der dir später bitter aufstoßen wird.

LG

Edit:
Ich hab eine solche Helfer-Klasse z.B. für die Registrierung des DataServices. Da bekommt die Helferklasse die Möglichkeit an bestimtme Konfigurationselemente ranzukommen - und je nach dem was konfiguriert wurde - werden dann eben spezifische DB-Implementierungen (Mssql, Mysql, etc.) in die ServiceCollection eingefügt.

13.10.2020 - 07:00 Uhr

Hi,

es gibt wirklich keinen Grund, weshalb deine Klassen in diesem Format überhaupt das Prinzip DI kennen sollten.

Beispiel:
Deine Controller in ASP.NET Core - die wissen nichts von DI - die haben im Normalfall schlicht einige Parameter im Konstruktor. Einfach um bei der Anwendung die Freiheit zu erhalten ob und wenn ja welches DI-Framework zum Einsatz kommt.

Wenn die Klasse überhaupt was vom DI-Framework weiß - oder sogar via DI die eigenen Abhängigkeiten auflöst - hast du effektiv Murks gemacht. DI machst du ja eben für lose Kopplung / leichte Austauschbarkeit - und nicht um die Kopplung noch zu verkomplizieren...

Um auf dein Beispiel zurückzukommen:
Wenn BLL1 die BLL2 braucht - dann bekommt sie diese eben per Konstruktor. In der eigentlichen Anwendung (dort in der Startup z.B.) kann man das dann gerne als Singleton via DI umsetzen - aber diese Funktionalität so vorzuschreiben ist in der Regel keine so tolle Idee, da du dann die Verwendung von DI vorschreibst und damit eine Kopplung (zur Microsoft DI) vorschreibst, welche sich überhaupt nicht austauschen lässt.

LG

01.09.2020 - 09:29 Uhr

Mir ging es damit nicht um bestimmte Normen - sondern vielmehr um die typisierte Vorgehensweise. Excel will genauso wenig alles string behandeln wie C#...

01.09.2020 - 07:43 Uhr

Hi,

ob das dein Problem behebt oder nicht ist mir nicht bekannt.

Soweit mir bekannt - arbeitet Excel mit DateTime genauso mit DateTime wie C#, nur dass das Startdatum zum Zählen ein anderes ist. Kurzum: Das ist eine speziell interpretierte Zahl - und kein string.

Dementsprechend sollte auch die Wertzuweisung aussehen - siehe z.B.:
https://bettersolutions.com/csharp/excel-interop/dates-datetime.htm

(Format brauchst du entsprechend auch)

LG

25.08.2020 - 15:16 Uhr

Hi,

wolltest du nicht weg von Excel? Dann scheidet Excel doch auch als Formelmanager aus - sonst kannst du es doch gleich so lassen...

Ich finde es zwar gut solche Formeln nicht hart im Code zu verankern - aber dann würde ich mir an deiner Stelle lieber einen Formelparser suchen und dann eine Art ManagerInterface dafür zu kreieren, das eben auch Doku enthalten kann.

Ich persönlich finde das Projekt "Flee" da ganz interessant - könntest du dir ja mal anschauen: https://github.com/mparlak/Flee

LG

07.08.2020 - 11:42 Uhr

Hi,

du brauchst doch gar kein static wenn du's ordentlich machst.

Gib den Pages entweder einen Verweis auf die Seitenverwaltung oder auf einen Service zur Seitenverwaltung.

Ich persönlich würde eine IPageNavigationService-Schnittstelle definieren, diese mit der Klasse PageNavigationService implementieren und dies entweder per DependencyInjection oder eben bei Erzeugung der Pages mitgeben, damit es einfach verwendet werden kann.

LG

30.07.2020 - 15:35 Uhr

Hi,

als Anmerkung und gerade wenn es etwas vielfältiger und komplexer wird kann es auch das Leben erleichtern, wenn man eine entsprechende Lib benutzt.

Für eine meiner Anwendungen habe ich z.B. https://www.nuget.org/packages/CommandLineParser/ verwendet.

Wobei die einfachste Möglichkeit (siehe @BerndFfm wenn du nur wenige und unkomplizierte Argumente brauchst) hier definitiv den Vorzug genießen sollte. Muss ja keiner das Rad neu erfinden...

LG

15.07.2020 - 15:16 Uhr

Hi,

die Fragestellung verwirrt ehrlich gesagt - zumindest wenn diese von einem Programmierer kommt.

Unabhängig von WPF - ihr habt eine startfähige Programmdatei, welche problemlos auch so programmiert werden könnte, dass diese auch Kommandozeilenargumente beherrscht - und bei entsprechenden Parameter eben keine UI zeigt - sondern irgendwo einen Report speichert.

Dabei helfen wird dir WPF wenig bis gar nichts - denn du willst ja nichts darstellen - und für die Reports selbst wird wohl eine wie auch immer geartete andere Lösung zum Einsatz kommen.

Grundlegend:
Ich würde sowas ggf. über die Windows Aufgabenplanung starten lassen und das bestehende Programm eben so erweitern, dass die .exe auch auf entsprechende Kommandozeilenbefehle reagiert.

LG

06.07.2020 - 08:16 Uhr

Hi,

falls du hier noch mal rein schaust:

Was immer du da mit dem Passwort treibst - hör bitte auf damit und nimm ein ordentliches System oder Vorbild für Authentifizierung.

Wer ein Passwort im Klartext im Jahr 2020 speichert dem gehört eigentlich die Schulbank.

Es gibt genug fertige Systeme - und selbst wenn du nicht gewillt bist ein fertiges zu nehmen - dann solltest du dir zumindest die Zeit nehmen nachzuforschen wie man das richtig macht.

LG

03.07.2020 - 17:52 Uhr

Hi,

ich persönlich würde in dieser Richtung wohl nicht weiter schauen. Bringt ja wenig nach irgendwelchen SysInternals zu suchen um das OS auszutricksen.

Generell allerdings: Wenn der Name des Adapters immer der selbe ist - wäre es zumindest sehr einfach ein kleines Script im Sinne von:


netsh interface ipv4 set address name="<name>" static <ip> <subnet> <gateway>

zu verwenden. Ist zwar nicht ganz so komfortabel wie komplett automatisch - aber wohl immer noch besser als komplett von Hand...

LG

01.07.2020 - 10:37 Uhr

Hi,

das klingt für mich nicht nach dem FileDialog selbst.

Hast du eine Art Vorschaufunktion aktiv, die bedingen könnte, dass eine solche Instanz geöffnet wird?

LG

09.06.2020 - 15:11 Uhr

Hi,

innerhalb des AddAuthorization-Aufrufs kommt man nicht an einen IServiceProvider und somit auch nicht an die Instanz des Lizenzservices bzw. dessen Optionen.

(Theoretisch kann man vorab manuell einen erzeugen - das ist aber unsauber und sollte vermieden werden)

Grundlegend sehe ich hier zwei Möglichkeiten:
a) Du baust eine "Option" und liest diese beim o.g. Aufruf auf und verwendest diese Option sowohl im Lizenzservice als auch im Requirement
b) Du hast sicher ohnehin schon eine eigene Implementierung eines AuthorizationHandlers - der bekommt sicher eh schon per DependecyInjection das notwendige Datum, womit das Requirement es hier schlicht nicht nötig hat

LG

04.06.2020 - 16:01 Uhr

Hi,

den Identity-Kram von Microsoft kann man zwar mit einer eigenen Datenzugriffstechnologie nutzen - es kann hier auch etwas umfangreicher werden.

Grundlegend:
Du musst einen eigenen IdentityStore schreiben, der (bei mir) folgende Schnittstellen implementiert:
IUserPasswordStore<IdentityUserEntity>, IUserClaimStore<IdentityUserEntity>, IRoleStore<IdentityRoleEntity>, IUserSecurityStampStore<IdentityUserEntity>, UserRoleStore<IdentityUserEntity>, IUserLoginStore<IdentityUserEntity>, IUserEmailStore<IdentityUserEntity>, IUserPhoneNumberStore<IdentityUserEntity>, IUserTwoFactorStore<IdentityUserEntity>, IUserLockoutStore<IdentityUserEntity>

Wie man das alles implementiert und anpasst - hängt prinzipiell von dir ab - aber die von Abt verlinkten Stellen waren bei mir vollkommen ausreichend um es auf meine Bedürfnisse mit eigenen Datenschnittstellen anzupassen.

Kann dir zwar ein Beispielprojekt verlinken - aber um ehrlich zu sein wird dich das nicht entscheidend weiter bringen, da es im Prinzip alles Boiler-Plate-Code ist um die bereits genannten Schnittstellen mit der eigenen Schnittstelle zu implementieren...

LG

02.06.2020 - 12:26 Uhr

Hi,

nein - so wird es genau nicht gemacht.

Wenn du einen Dispatcher in der selben Methode wie eine MySqlConnection verwendest - machst du es im Prinzip schon falsch. (siehe bereits verlinkten Artikel 3-Schichten-Architektur)

Kurz: Ein Dispatcher gehört zur UI - eine Connection zur Datenbank. Beide in der selben Methode zu verwenden zeigt nur, dass du eben nicht getrennt hast wie es sich gehört.

Warum man das so klar sagen kann?
Den Dispatcher verwendet man um eine asynchrone Datenänderung mit dem "UI-Thread" von WPF abzufangen, sodass du UI darüber eben im "richtigen" Thread informiert wird. Wenn du jetzt einen Dispatcher (und auch noch eine Liste, welche der UI bekannt ist - aus der Datenschicht aktualisieren lässt - dann kann das nur falsch sein)

Kann jetzt natürlich sein, dass der Dispatcher komplett unnötig verwendet wurde - aber dann solltest du aufhören einfach Code zu kopieren...

LG

25.03.2020 - 19:09 Uhr

@Abt - ich leider auch nicht - ich hatte nur gehofft jemand hätte mal versucht auf dem Standard-MS-Image sich simpel mit einem Port zu verbinden.

@david.m
Hatte es bislang nicht erwähnt - aber mit einer der ersten Tests meinerseits war das simple Öffnen eines Ports, was problemlos durchging. (Auch ohne "-t"^^)
Zusätzlich hatte ich den UnitTest auch mal mit Port 50.000 ausgeführt.
Trotzdem Danke 😃

LG

PS:
Ich denke das weitere Verfolgen dieses Anliegens wird hier keinen so großen Zweck haben. Wenn keiner SMTP auf diese Art testet ist das wohl einfach nicht die Art, wie man das Problem angeht. (Wollte ja nur gründlich sein) Hab meine eigentlichen Klassen und UnitTests (diesmal wirklich) nun so umgeschrieben, dass alles was nicht gerade wirklich getestet wird per Moq gemockt wird. (Obwohl ich noch "etwas" an der Verifizierung eines IMailTransport.Send knabbere - das wird aber schon noch)

25.03.2020 - 17:48 Uhr

Hi,

vielen Dank für die Antwort und die Tipps.

Ok - dass damit keine Tests ausgeführt werden war mir nicht bewusst. Schade.

Nunja - dass der Fehler im Test liegt - ich führe diese ganzen Tests ja auch lokal aus - vollkommen ohne jedes Problem - und alle erfolgreich. (Dort führe ich das ganze per VS/ReShaper aus) Demnach sollte der Fehler doch eher in der Umgebung zu suchen sein. Korrekt? (Ist auch nicht so, als ob ich die Tests nur auf dem Server ausführe...)

Habe mal die Änderungen am CI vorgenommen und ein Timeout für den Client gesetzt.
Vom Grundprinzip hast du Recht - es ist ein Timeout, dass beim Connecten auftritt.
Aber wieso tritt das lokal nicht auf - aber auf diesem Docker-System?> Fehlermeldung:

X DoMailTest [185ms]
Error Message:
Test method FluiTec.AppFx.Networking.Mail.Tests.MailTest.DoMailTest threw exception:
System.IO.IOException: Connection timed out ---> System.Net.Sockets.SocketException: Connection timed out
Stack Trace:
at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at MailKit.Net.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
--- End of inner exception stack trace ---
at MailKit.Net.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at MailKit.Net.Smtp.SmtpStream.ReadAheadAsync(Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Smtp.SmtpStream.ReadResponseAsync(Boolean doAsync, CancellationToken cancellationToken)
at MailKit.Net.Smtp.SmtpStream.ReadResponse(CancellationToken cancellationToken)
at MailKit.Net.Smtp.SmtpClient.DataAsync(FormatOptions options, MimeMessage message, Int64 size, Boolean doAsync, CancellationToken cancellationToken, ITransferProgress progress)
at MailKit.Net.Smtp.SmtpClient.SendAsync(FormatOptions options, MimeMessage message, MailboxAddress sender, IList`1 recipients, Boolean doAsync, CancellationToken cancellationToken, ITransferProgress progress)
at MailKit.Net.Smtp.SmtpClient.Send(FormatOptions options, MimeMessage message, CancellationToken cancellationToken, ITransferProgress progress)
at MailKit.MailTransport.Send(MimeMessage message, CancellationToken cancellationToken, ITransferProgress progress)
at FluiTec.AppFx.Networking.Mail.Tests.MailTest.DoMailTest() in /builds/fluitec/fluitec.appfx.networking/src/tests/FluiTec.AppFx.Networking.Mail.Tests/MailTest.cs:line 23

Am öffnen des Ports scheint es ja nicht zu hapern - warum also beim verbinden?

Was den Integrationstest angeht - ja das ist kein feiner UnitTest - grundlegend hatte ich aber hier die Optionen einen SmtpClient zu mocken (der in meinem Teil der API bislang gar nicht öffentlich zur Verfügung steht) und dort zu validieren - oder eben einen simplen SmtpService anzubieten, der eine Validierung erlaubt.

In anderen Worten: Du empfiehlst somit eher dem Client zu mocken?

LG und Vielen Dank

PS: Nunja - ein funktionierendes Verhalten gegenüber dem nDumbsterCore hat mir durchaus einen Mehrweg gebracht. Hab schnell gesehen, dass ich einige Paramter bei der Weitergabe getauscht hatte. Sicher - das ist kein echter SMTP-Server und soll es auch niemals werden, da ich gar keine Mails verschicken möchte in simplen Tests. Auf der anderen Seite verhält sich auch nicht jeder SMTP-Server wie der andere, womit ein solcher Test besser als nichts - aber auch sicher weniger gut als das Produktivsystem ist...

25.03.2020 - 10:17 Uhr

Hi,

vorab - für mehr Details - ich hatte bereits im Gitlab-Forum nachgefragt (siehe somit https://forum.gitlab.com/t/gitlab-runner-trying-to-open-and-listen-on-a-port-using-mstest-netcore-for-smtp/35585)

Grundlegend geht es um Folgendes:
Ich schreibe UnitTests die auch SMTP testen sollen - deshalb verwende ich quasi eine Minimalimplementierung eines SMTP-Servers (nDumbsterCore). Lokal - funkioniert das hervorragend - im Gitlab-Runner gibt's ein Timeout nach dem Entdecken der Tests ohne mir die Möglichkeit zu geben auch nur den geringsten Output zu erhalten.

Ursprünglich dachte ich, dass entweder das öffnen oder das verbinden zu einem so geöffneten Port Ärger mit sich bringt. Wie es scheint - ist das nicht der Fall. Denn das hinzufügen von "-t" zu dotnet test - genügt um den Test laufen zu lassen. Sogar parallelisiert.

Für mich steht fest: Das darf kein solches Problem beheben.

Die Fragen die sich mir nun stellen:
a) Warum behebt dieses Flag das Problem?
b) Stell ich mich selbst doof an?
c) Falls b) nicht zutrifft - wo kann ich ein entsprechendes Issue melden?
Gitlab oder eher Microsoft? (und wo genau?)

Für den Fall, dass jemand die Muße hat mein Problem nachzustellen:
a) Eine kurze C#-Klasse, welche genügt um im Gitlab-Runner ein Timeout auszulösen
Datei: MailTest.cs


using MailKit.Net.Smtp;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using MimeKit;
using MimeKit.Text;
using nDumbsterCore.smtp;

namespace FluiTec.AppFx.Networking.Mail.Tests
{
    [TestClass]
    public class MailTest
    {
        [TestMethod]
        public void DoMailTest()
        {
            var server = SimpleSmtpServer.Start(25);

            using (var client = new SmtpClient())
            {
                client.ServerCertificateValidationCallback = (sender, certificate, chain, errors) => true; // accepts all certs
                client.Connect("127.0.0.1", 25, false);
                client.AuthenticationMechanisms.Remove("XOAUTH2");
                client.Send(new MimeMessage
                {
                    From = { new MailboxAddress("Test", "test@example.com") },
                    To = { new MailboxAddress("Test", "test@example.com") },
                    Subject = "Subject",
                    Body = new TextPart(TextFormat.Plain)
                });
            }

            server.Stop();
        }
    }
}

b) Eine CI-Yaml-Datei um das Problem zu demonstrieren
Datei: .gitlab-ci.yml


image: mcr.microsoft.com/dotnet/core/sdk:3.1

stages:
    - build
    - test

variables:
    srcDir: "src"
    
before_script:
    - "cd $srcDir"
    - "dotnet restore"

build:
    stage: build
    script:
        - "dotnet build"
        
test:
    stage: test
    script:
        - "dotnet test" # funktioniert nicht (Timeout)
        - "dotnet test -t" # funktioniert (kein Timeout)

LG

18.03.2020 - 11:36 Uhr

Hi,

im Prinzip genügen bei dir zusätzliche 2 x else if und einmal else mit einer entsprechend sinnvollen Ausgabe.

Und den Quotient brauchst du in der Tat nicht.

LG

13.03.2020 - 11:45 Uhr

Hi,

nun ja - Möglichkeiten gibt es hier viele.

If-Else würde funktionieren, du kannst aber auch auch objektorientierter arbeiten und quasi ein Ruleset dafür bauen mit welchem du nicht so viele Verzweigungen brauchst.

Im einfachsten Fall könnte es dann so aussehen:


public static double GetDiscount(int amount)
    {
        if (amount >= 5)
            return .2;
        if (amount == 4)
            return .15;
        if (amount == 3)
            return .1;
        return 0;
    }

LG

25.02.2020 - 07:04 Uhr

Hi,

nun - jede DLL ist leider zu viel erwartet.

Jede DLL die in .NET Standard bzw. .NET Core verfügbar ist.

Es ist zwar richtig, dass extrem viele Libraries nun per .NET Standard verfügbar sind - aber es sind auch lange nicht alle.

Womit ich anfangs häufiger Probleme hatte betraf meist folgende Bereiche:

  • Zeichnen
  • Reflection
  • teils Kryptografie
    (wobei ich gestehen muss, dass das teils etwas länger her ist - ich gehe davon aus, dass mittlerweile die API-Abdeckung vollständiger ist)

Grundlegend: Wenn ihr Projekte verwendet, die nicht wirklich aktiv gepflegt werden oder aufgrund API-Schwachstellen nicht portiert wurden kann das schon ein Problem werden. Wobei ich mittlerweile erwarten würde, dass .NET Standard und .NET Core ausreichend Möglichkeiten bieten um nicht bei der Portierung "stecken zu bleiben".

20.02.2020 - 13:20 Uhr

Hi,

naja - dafür gibts verdammt viele mögliche Vorgehensweisen.

Etwas in einer Datei speichern
Etwas in der Registry speichern
Datenbank, WebService, etc.

Such dir was aus - probier ob du's schaffst - und wenn du auf Probleme stößt - kannst du ja hier nochmal nachfragen.

LG

19.02.2020 - 10:21 Uhr

Hi,

im Grunde kann ich nicht wirklich weiterhelfen - du versuchst hier quasi eine manuelle Cookie-Authentifizierung oder?

Fakt ist: Was du dort tust ist kein für ASP.NET Core nachvollziehbarer Login, womit du eine Art Authentication-Loop für den User gebaut hast.

Beispiel:
User ruft Home/Index auf
-> ASP.NET Core stellt fest: User ist nicht angemeldet
-> ASP.NET Core verweist Auth/Login
User postet seine Credentials
-> Du denkst, dass du den Benutzer erfolgreich anmeldest
-> Du leitest wieder auf Home/Index um
-> siehe Schritt 1 (ASP.NET Core stellt fest: User ist nicht angemeldet) und der Loop beginnt von vorn

Falls du das mit manuellen Cookies machen möchtest würde ich dir folgende Seite empfehlen:
https://docs.microsoft.com/de-de/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1

LG

10.02.2020 - 18:30 Uhr

Hi,

da dir offenbar noch jede Übersicht fehlt - nachfolgend einmal ein Link für eine Beispielimplementierung (bitte nur als Orientierungshilfe verwenden):
https://social.technet.microsoft.com/wiki/contents/articles/25726.wpf-implementing-custom-authentication-and-authorization.aspx

ACHTUNG:
Dort wird gezeigt, wie explizit auf bestimmte Rollen überprüft wird - das ist eigentlich längst überholt und auch oft nicht so flexibel wie man das in vielen Fällen gerne hätte. Grundlegend ist es meist gut zumindest auf Basis von Aktivitäten zu autorisieren. (siehe z.B. https://lostechies.com/derickbailey/2011/05/24/dont-do-role-based-authorization-checks-do-activity-based-checks/)

Ab davon bleibt aber die Frage:
Was genau gedenkst du in WPF abseits von bestimmten Ausblendungen zu erreichen?

Grundlegend sollten entsprechende Autorisierungsmechanismen natürlich nicht nur auf die Schicht der Oberfläche angewendet werden, sodass der User und dessen Rechte auch in anderen Schichten bekannt ist und genutzt wird. Letztlich führt das dann aber auch nur wieder dazu, dass bestimmte Sachen ausgeblendet sind 😉

LG

10.02.2020 - 12:04 Uhr

Hi,

naja - wenn du damit die notepad.exe von Microsoft meinst und der Text dort auch 1 zu 1 lesbar wie im Original ist - dann handelt es sich um eine PlainText-Datei, die mit C# ohne weitere Bordmittel auslesbar ist.

Falls dem so ist - wird dir jede Google-Suche nach "C# read text file" zahllose Ergebnisse bieten. Der Rest ist ja ohnehin deine Logik und sah ebenfalls nicht weiter kompliziert aus.

LG

07.02.2020 - 11:21 Uhr

Hi,

möglich scheint es auf den ersten Blick.

Grundlegend ist mir nicht ganz klar, ob SDF nun zu StarOffice oder wirklich zu OpenOffice gehören.

OpenOffice aus C# selbst anzusprechen scheint (auf den ersten Blick) eine ziemlich miese Aufgabe zu sein - sehr aufwändig und schwierig. Offenbar werden dafür zumeist (wenn überhaupt) kommerzielle und kostenpflichtige Suites angeboten, welche auch wieder nur mit den Standarddokumenten klar kommen.

Auf Basis dessen - würde ich persönlich wohl eher versuchen die sdf-Dateien (die ja scheinbar automatisiert erstellt werden?) in ein leichteres Format umwandeln (dafür würde ich wohl eine Art Script suchen - siehe z.B. http://manpages.ubuntu.com/manpages/trusty/man1/sdf.1.html - falls das überhaupt geht)

Und Html-Dateien würden sich auch deutlich einfacher auswerten lassen in C#.

LG

07.02.2020 - 11:07 Uhr

Hi,

direkt helfen kann bzw. mag ich nicht direkt - es sollte aber recht einfach sein sich das ganze Zusammenzuklamüstern aus der API-Beschreibung und einigen Aufzeichnungen mit dem Makroeditor.

Mein Tipp: Mach von Hand was du vorhast - und lass den Makroaufzeichner mitlaufen - das übersetzt und wandelst du nach C# und dann hast du eine gute Basis.

LG

18.01.2020 - 19:32 Uhr

Hi,

grundlegend halte ich die Vorgehensweise so viele einzelne Buttons separat anzusprechen für unschön.

Viel schöner wäre es doch, wenn du die 9 Buttons einer Liste hinzufügst. Dann hast du die Möglichkeit diese Liste auf unbeschriftete Buttons zu filtern und per Random.Next einen zufälligen Button zum Beschriften auszuwählen.

Damit wäre das Ganze deutlich übersichtlicher und wohl auch etwas leichter auszuformulieren.

LG

Edit - etwas auf dieser Basis:


var buttons = new List<Button>(new Button[] {
            new Button(),
            new Button(),
            new Button(),
            new Button(),
            new Button(),
            new Button(),
            new Button(),
            new Button(),
            new Button()
        });
        
        var unusedButtons = buttons.Where(b => string.IsNullOrWhiteSpace(b.Text)).ToList();

07.01.2020 - 15:29 Uhr

Hi,

du verwendest falsche Begriffe zum Suchen.

Eine exe hat keinen Rückgabewert - sondern eine Ausgabe. (Eigentlich sogar mehrere)

Diese kann man mit C# abrufenund entsprechend reagieren -- zum googeln empfehle ich entsprechend: c# exe capture output

LG

18.12.2019 - 10:57 Uhr

Hi,

öm - nunja - in der Praxis: halbwegs beides und stark abhängig davon was du machst und brauchst.

Mein Tipp: Lies dich erst mal bitte in den folgenden Artikel ein:
[Artikel] Drei-Schichten-Architektur

Ich hoffe dann siehst du schon klarer.

Leider ist deine Frage in dieser Form nicht vollständig zu beantworten... Aber grundlegend gibt es eigentlich immer eine Datenschicht, in der es je Tabelle auch eine Klasse gibt.

LG

09.12.2019 - 07:56 Uhr

Hi,

Vielen Dank für die Antwort.

Falls relevant - ich arbeite aktuell um genau zu sein mit .NetCore 3.1.

Das mit "Index" sieht jedenfalls fischig aus

Recht hast du - hab den Controller nun folgendermaßen korrigiert:

[Route("StatusCode/{id}")]
        public IActionResult Index(int id)
        {
            var reExecute = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
            if (reExecute != null)
            {
                _logger.LogInformation($"Status Code: {id}, OriginalPath: {reExecute.OriginalPath}");
            }

            return View(id);
        }

Allerdings - mein Problem bleibt - per Redirect erhalte ich meine View zurück - per Reexecute erhalte ich einen nackten 404. Ich habe testweise mal das Logging auf Debug gestellt - allerdings gibt das auch sehr wenig Aufschluss...

app.UseStatusCodePagesWithRedirects("/StatusCode/{0}");

führt zu:


Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 GET http://localhost:60422/Home/234  
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware: Debug: The request path /Home/234 does not match a supported file type
Microsoft.AspNetCore.Routing.Matching.DfaMatcher: Debug: No candidates found for the request path '/Home/234'
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware: Debug: Request did not match any endpoints
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 17.2046ms 302 
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 GET http://localhost:60422/StatusCode/404  

Hab den Controller für Reexecute mal angepasst:


public IActionResult Code(int code)
        {
            var reExecute = HttpContext.Features.Get<IStatusCodeReExecuteFeature>();
            if (reExecute != null)
            {
                _logger.LogInformation($"Status Code: {code}, OriginalPath: {reExecute.OriginalPath}");
            }

            return View("Index", code);
        }

app.UseStatusCodePagesWithReExecute("/StatusCode/Code", "?code={0}");

führt zu:


Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request starting HTTP/1.1 GET http://localhost:60422/x324  
Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware: Debug: The request path /x324 does not match a supported file type
Microsoft.AspNetCore.Routing.Matching.DfaMatcher: Debug: No candidates found for the request path '/x324'
Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware: Debug: Request did not match any endpoints
Microsoft.AspNetCore.Hosting.Diagnostics: Information: Request finished in 63.9491ms 404 

Weitere Einfälle?

LG

07.12.2019 - 16:35 Uhr

Hi,

ich versuche gerade mich mit EndpointRouting auseinanderzusezten und habe leider Gottes ein Problem. Vom Prinzip hat das EndpointRouting ja sicher seine Vorteile - aber nach jeder Menge Tests muss ich feststellen: Das IStatusCodeReExecuteFeature ist nicht mehr funktionsfähig damit - sehe ich das richtig?

Mein Problem:
Verwende ich MVC kann ich problemlos mit Hilfe des vorgenannten Features einen HTTP404 samt trotzdem einer netten Seite aus einem Controller zurückgeben (und zwar unter Berücksichtigung des originalen Paths) - mit EndpointRouting wird das IStatusCodeReExecuteFeature schlicht gar nicht berücksichtigt bzw. ich kann ihn dazu nicht bewegen.

Als Beispiel:
(Dieser Code verwendet Redirects, womit ein (eigentlicher) 404 mit einem 302 und einem entsprechenden Redirect beantwortet wird - mies, denn eigentlich will ich ja den originalen Path und StatusCode)
--> Dieses Beispiel funktioniert problemlos - vorausgesetzt man hat einen entsprechenden StatusCodeController


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseStatusCodePagesWithRedirects("/StatusCode/Index/{0}");
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }

Beispiel 2:
(Dieser Code soll ein Reexecute ausführen - macht jedoch letztendlich rein gar nichts, womit ein 404 (von welcher Pipeline auch immer) mit dem schlichten StatusCode 404 - und sonst gar nichts) beantwortet wird)


public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
            }
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            app.UseStatusCodePagesWithReExecute("/StatusCode/Index/{0}");
            app.UseEndpoints(endpoints =>
            {
                endpoints.MapDefaultControllerRoute();
            });
        }

Meine Fragen:
a) Mache ich was falsch?
b) Geht das überhaupt noch was ich beabsichtige?
c) Gibt es einen Umweg zum Ziel?

LG

05.12.2019 - 08:14 Uhr

Hi,

wärst du so freundlich die richtige Fehlermeldung hier rein zu kopieren?

Habe wenig Lust darauf das Ganze nachzustellen nur um eine nützliche Fehlermeldung zu sehen 😉

LG

Edit: Auf Basis der MSDN sieht die Sache etwas umfangreicher aus - um Shapes verwenden zu können - braucht man scheinbar einen ShapeContainer - vermutlich ist nur dieser tatsächlich ein Control und könnte der Form entsprechend hinzugefügt werden.

Insofern noch einmal mein Tipp: Mach eine Beispielform - schau was der Designer kreiert, damit es funktioniert - und baue dies entsprechend in deine Methode(n) ein.

05.12.2019 - 06:58 Uhr

Hi,

RectanlageShape ist ein Control, dass der Form bekannt gemacht werden muss - üblicherweise geschieht das über ein Form.Controls.Add(x); - würde dir empfehlen, dir einfach jeweils den generierten Beispielcode des Designers als Vorlage zu nehmen.

04.12.2019 - 14:42 Uhr

Hi,

nicht wirklich in "C#" - aber scheinbar verfügbar per WMI und PInvoke. Siehe:
https://stackoverflow.com/questions/7470214/create-network-share-with-permissions

LG

04.12.2019 - 07:15 Uhr

Hi,

nun - das Property TotalHours sieht hierfür vielversprechend aus:


public static string FormatHours(TimeSpan ts) {
        return string.Format($"{Math.Floor(ts.TotalHours):00}:{ts.Minutes:00}");
    }

(TotalHours ist ein Double, der bei dieser Formatierung gerundet würde - deshalb muss von vor Ausgabe abrunden)

LG

02.12.2019 - 06:56 Uhr

Hi,

kann mich zwar sicher nicht als Profi bezeichnen - auf der anderen Seite:
Wenn dir dein eigener Code nicht gefällt ist das wichtigste Grundkriterium doch erfüllt.

Ich mach das häufig, dass ich Projekte die ich vor längerer Zeit erstellt hatte öffne. In vielen Fällen kann ich die Dinger nicht mehr zumachen ohne zu korrigieren was mir nun schon peinlich ist. (Und in vielen Fällen zieht das auch einen Neustart des Projekts nach sich...)

Kann dir nur empfehlen dir immer wieder Artikel über DesignPattern anzuschauen - schau dir auch andere Projekte auf GitHub an - arbeite dich in die Klassenstrukturen anderer rein und versuche tiefgreifende Funktionen zu verstehen und ggf. abzuändern - gerade in komplexeren Systemen.

LG

26.11.2019 - 14:17 Uhr

Hi,

in anderen Worten macht man das "nur" um ein sinnvolles auf Environments angepasstes Bundling zu erreichen? Nun denn - das macht zumindest Sinn 😃

26.11.2019 - 12:44 Uhr

Hi,

ich versuche mich gerade erstmalig in SPA's einzuarbeiten.

Was mich ein wenig wundert:
Wieso ist z.B. das Hosting einer Angular-Anwendung direkt in ASP.NET Core eingebaut?

Wäre es nicht sauberer, das ganze als separates Projekt zu handeln - und dort ohnehin mit VS-Code und separat mit Node.js zu arbeiten? Oder gibt es einen guten Grund das ganze innerhalb von von ASP.NET Core zu halten?

Nicht, dass ich mir später das Leben unnötig schwer mache...

LG

20.11.2019 - 11:51 Uhr

Hi,

eine Sache vorweg:
Wir haben extra Code-Tags im Forum - bitte poste deinen Code damit - PDF's wird sich eigentlicher keiner anschauen wollen wenn's um Code geht.

Du hast scheinbar einen Logikfehler in deinem Code, bei dem jeder andere hier im Forum ein Problem haben wird es nachzuvollziehen - das hat bei dir mehrere Gründe:
a) Keiner hier kann deinen Code in eine IDE kopieren (UI-Teil fehlt)
b) Deine Variablennamen machen für Außenstehende ohne detailliertere Beschäftigung wenig Sinn (noch weniger als für dich, der du offensichtlich schon nicht mehr durchblickst)
c) Du hast Logik mit UI vermischt (auch daher kann keiner den Code einfach kopieren)

Mein Tipp zur Selbsthilfe:
Trenne Logik und UI - z.B. durch eine extra-Berechnungsklasse - wenn du dabei aufpasst hast du deinen Fehler mit hoher Wahrscheinlichkeit selbst gefunden - in jedem anderen Fall - kommst du diesem mit Hilfe des Debuggers sehr leicht auf die Spur.

LG