Zertifikats- / SSL-Fehler im WebClient ignorieren

Hin und wieder kommt es vor, dass auf Web-Ressourcen zugegriffen wird. Aber was passiert, wenn die lokale Anwendung das Zertifikat nicht akzeptiert? Die Anwendung würde eine Exception auslösen und nicht mehr wie erwartet ablaufen. Mir begegnete das Problem zuletzt, als ich die Zertifikate eines Servers aktualisiert habe und anschließend die Anwendung unter Windows XP nicht mehr lief. Der dortige Internet Explorer konnte mit den neuen Zertifikat nicht umgehen. Zum Glück aber, kann ein solches Problem recht einfach mit nur einer Zeile gelöst werden. Um jedes Zertifikat zu akzeptieren, benötigt der Quellcode nur auf dem Aufruf der Web-Ressource folgende Zeile:

ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

Natürlich können hier auch eigene, komplexe Methoden implementiert werden, um z.B. nur bestimmte Zertifikate zuzulassen.

RadioButtons und Binding in .NET 3.5

Im .NET-Framework 3.5 haben RadioButtons eine merkwürdige Eigenschaft. Sie überschreiben das Binding der IsChecked Property beim Uncheck. Da dies nur in den seltensten Fällen gewollt sein kann, dass sich das Binding verabschiedet, wurde dies im .NET 4.0 behoben. Aber auch unter .NET 3.5 kann der Fehler mit Hilfe eines kleinen Workarounds umgangen werden. Hierzu muss nur eine eigene RadioButton-Klasse erstellt werden, welche ein paar Dinge mit sich bringt. Anschließend wird in der Anwendung das Binding nicht mehr bei der Property „IsChecked“ sondern bei der Property „IsCheckedBinding“ gesetzt. Hier der benötigte Code zum eigenen Control:

using System.Windows;
using System.Windows.Controls;

public class DataBoundRadioButton : RadioButton
{
    private static bool _isChanging;

    public static readonly DependencyProperty IsCheckedBindingProperty =
            DependencyProperty.Register("IsCheckedBinding", typeof(bool), typeof(DataBoundRadioButton),
            new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.Journal | FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, IsCheckedBindingChanged));
        
    public bool IsCheckedBinding
    {
        get { return (bool) GetValue(IsCheckedBindingProperty); }
        set { SetValue(IsCheckedBindingProperty, value); }
    }

    public DataBoundRadioButton()
    {
        Checked += OnChecked;
        Unchecked += OnUnchecked;
    }

    private void OnChecked(object sender, RoutedEventArgs e)
    {
        if (!_isChanging)
            IsCheckedBinding = true;
    }

    private void OnUnchecked(object sender, RoutedEventArgs e)
    {
        if (!_isChanging)
            IsCheckedBinding = false;
    }

    private static void IsCheckedBindingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        _isChanging = true;
        ((DataBoundRadioButton)d).IsChecked = (bool)e.NewValue;

        _isChanging = false;
    }
}

Administratorrechte für eine Anwendung erforderlich machen

Es gibt Fälle, in denen man nicht darum herumkommt, für eine Anwendung Administratorrechte erforderlich zu machen. Egal, welche Sprache man wählt, immer kann es nötig sein Aktionen durchzuführen für die mehr Rechte erforderlich sind, als die eines normalen Benutzers. Im Visual Studio kann man hierfür der Anwendung einfach eine Manifest-Datei hinzufügen. Diese Anwendungsmanifest-Datei ist eine simple XML-Struktur. Weiterlesen

Mit C# in der Windows-Ereignisanzeige schreiben

Wenn es um das Thema „Logging“ geht, gibt es bei C# beliebig viele verschiedene Ansätze. Neben den weit verbreiteten Logging-„Frameworks“ wie u.a. log4net, besteht in C# ebenfalls die Möglichkeit in den Windows-„Log“ (im Deutschen Ereignisanzeige) seine Fehler und andere Probleme abzulegen. Aber was wird benötigt, um dorthin schreiben zu können? Nun zunächst muss die Anwendung, um dorthin schreiben zu können, seit Windows Vista im Administrator Modus laufen. Wie man dies für die Anwendung voraussetzen kann, folgt noch in einem weiteren Blog-Post, lässt sich aber auch schnell mittels Google lösen. Stichwort: Manifest. Weiterlesen

C# 6.0 – Dictionary Initialisierung

Mit C# 6.0 lassen sich auch Dictionaries direkt initsialisieren. Dabei spielt es auch keine Rolle welche Typen verwendet werden. Da hier nicht viel Erklärungbedarf bestehen dürfte, hier ein selbsterklärendes Beispiel (es werden Zeilennummern C++ Quellcodezeilen zugewiesen und im Dictionary gespeichert):

Dictionary<int, string> CppHelloWorldProgramCode = new Dictionary<int, string>
    {
        [1] = "#include <iostream>", 
        [2] = "", 
        [3] = "int main () {", 
        [4] = "  std::cout << \"Hello World!\" << std::endl;", 
        [5] = "  return 0;", 
        [6] = "}"
    };

C# 6.0 – Wie heißt du denn?

Um in C# 6.0 zu erfahren, wie eine Variable im Quellcode heißt, gibt es das neue Schlüsselwort „nameof„. Mit dessen Hilfe kann z.B. ein Umbennen von Variablen, welche anschließend im Logging oder Exception-Text (-Parameter) verwendet werden, so gestaltet werden, dass der Kompiler einen Fehler ausgibt, wenn die Bezeichnung nicht stimmt. Hier ein Beispiel:

public void DoSomething(string someValue)
{
    if (string.IsNullOrEmpty(someValue))
        throw new ArgumentException(nameof(someValue), $"A value for parameter \"{nameof(someValue)}\" is required!");

    // Do some stuff here
}

Und so reiht sich die neue Funktionalität wunderbar in der Sammlung positiver Aspekte von  C# ein.

SecureString effektiv nutzen und verwenden

Mit Hilfe der Klasse SecureString ermöglicht das .NET-Framework auch String Daten nicht vollig entblößt im Arbeitsspeicher abzulegen, um z.B. den Zugriff von anderen Applikationen zu vermeiden. Leider ist mit SecureString nicht allzu einfach umzugehen und es kommt vor, dass man diesen für Momentaufnahmen dennoch als normalen String im Speicher benötigt, um damit z.B. den Inhalt in einer Oberfläche anzuzeigen oder um die Daten speichern zu können. Hier kann mit der Hilfe von Datentyp-Extensions gut Abhilfe geschaffen werden. So können wir uns Methoden implementieren, die es uns ermöglichen auch den SecureString wieder im Quellcode effektiv zu nutzen und dennoch parallel die Sicherheit zu verbessern (auch wenn zur absoluten Sicherheit die Rückwandlung nicht möglich sein sollte). Weiterlesen

Wie wird in C# gerundet?

Das umwandeln von Float, Double oder Decimal in einen Integer funktioniert in C# nach der IEEE 754 Definition und ist somit nicht immer wie man es erwarten würde, wenn man nur den kaufmännischen Weg kennt. Zunächst einmal sollte erwähnt werden, dass es verschiedene Wege gibt aus einer Gleitkommazahl eine Ganzzahl zu machen. Ich werde euch hier die einzelnen Wege einmal vorstellen.

Der erste Weg, ist das direkte Umwandeln durch einen Datentyp-Cast. Hierbei werden jedoch Nachkommastellen einfach abgeschnitten statt wirklich gerundet zu werden. Dies würde wie folgt aussehen:

float myFloat = 4.8f;
int myInteger = (int)myFloat; // myInteger wird nun 4 sein.

Die nächste Möglichkeit ist das Umwandeln von Typen über die Convert-Klasse aus dem .NET-Framework.

float myFloat = 4.8f;
int myInteger = Convert.ToInt32(myFloat); // myInteger wird nun 5 sein.

Hierbei würden wir augenscheinlich zunächst das richtige Ergebnis erhalten, aber was ist, wenn unsere Zahl genau in der Mitte liegt? Hier kommt es dann zum Problem.

int myInteger1 = Convert.ToInt32(8.5); // myInteger1 wird nun 8 sein.
int myInteger2 = Convert.ToInt32(9.5); // myInteger2 wird nun 10 sein.

Um das Problem kurz aufzulösen: Hierbei wird immer zur nächsten geraden (sprich durch zwei teilbaren) Zahl gerundet. Im Falle von 8,5 also zur 8 und im Falle von 9,5 zur 10. Leider kommt es zu dem gleichen Problem, wenn man die Methode Math.Round verwendet. Es sei den, man benutzt eine Überladung für die Math.Round Methode unter der Angabe des „MidpointRounding„-Parameters. Mehr Informationen dazu gibt es hier:
https://msdn.microsoft.com/en-us/library/system.midpointrounding.aspx

C# 6.0 – Auf NULL prüfen vereinfachen

Eine weitere Neuerung in C# 6.0 ist das vereinfachte prüfen, ob eine Variable „NULL“ ist oder ob diese bereits initialisiert worden ist. Der hierfür benötigte Operator ist das „?“, welches auch bereits bei Nullable-Typen verwendet wird. Hier ein kleines Beispiel der Verwendung:

string sTest = "Hello World";

char? thirdChar = sTest?[2]; // 'l'

sTest = null;
thirdChar = sTest?[2]; // null

sTest = "Hi";
thirdChar = sTest?[2]; // throws IndexOutOfRangeException

Auch dies erspart dem Programmierer wieder ein paar Zeilen, jedoch finde ich es zum jetzigen Zeitpunkt noch merkwürdig zu lesen. Wobei das wohl vergehen wird, wenn erst einmal die Übung mit besagter Funktionalität etabliert ist.

C# 6.0 – Lambda Expressions für Read-Only Properties

Als Ergänzung zu der Möglichkeit, in C# 6.0 ganze Methoden durch Lambda Expressions zu ersetzen, ist dies auch mit Read-Only Properties sehr simpel  möglich. Hierzu muss lediglich ein ähnlicher Aufbau wie bei den Methoden verwendet werden.

public string Name { get; private set; } 
public string BackwardsName => new string(Name.Reverse().ToArray());