.NET Framework
Not everyone has been as fortunate as I to work with the .NET Framework from its beginning. So, here’s just a quick recap and introduction to the .NET Framework.
The .NET Framework is a computing platform that aids in application development. The purpose of the .NET Framework is to provide a code-execution environment:
- That minimizes software deployment and versioning conflicts.
- That guarantees safe execution of your code, as well as code created by a third party.
- That eliminates the performance problems of scripted environments.
The .NET Framework consists mainly of these two components:
- The Common Language Runtime (CLR)
- The .NET Framework class library
CLR (Common Language Runtime)
The Common Language Runtime (CLR) manages the execution of .NET programs. With the Common Language Runtime, it is easy to design components and applications whose objects interact across different languages. Objects written in different languages can communicate with each other, and their behaviors can be tightly integrated.
.NET Framework Class Library (FCL)
The FCL (.NET Framework Class Library) is a library of classes and other types that developers use to make their lives easier. The .NET Framework class library is a collection of reusable types that tightly integrate with the common language runtime (CLR).
I have spoken about the .NET Framework before on several occasions. These articles list some .NET Framework related topics I have covered:
- Exciting Times for .NET as Companies Join the .NET Bandwagon
- The Future of .NET Languages
- What’s New in Visual Studio 2017?
- .NET Framework Knowledge Checklist for 2017
.NET Framework 4.7
In April 2017, Microsoft announced that .NET Framework 4.7 would be integrated into Windows 10 Creators Update. A standalone installer for other Windows versions was also released soon after, as well as an update for Visual Studio 2017 that added support for targeting .NET Framework 4.7.
New features in .NET Framework 4.7 include:
- Improved serialization by the DataContractJsonSerializer
- Improved Transport Layer Security (TLS) support
- Enhanced cryptography with elliptic curve cryptography
- Support for High-DPI awareness support in Windows Forms
DataContractJsonSerializer
The DataContractJsonSerializer class serializes objects to the JavaScript Object Notation (JSON) and deserializes JSON data to objects. Here is small example for Visual Studio 2017:
Serialize
To define the data contract for a Student
Define the data contract for Student by adding the DataContractAttribute to the class and adding the DataMemberAttribute attribute to the members that you want serialized. Create a class and enter the following:
C#
[DataContract] internal class Student { [DataMember] internal string StudentName; [DataMember] internal string StudentSurname; [DataMember] internal int StudentNumber; [DataMember] internal int StudentCourse; }
VB.NET
<DataContract> _ Friend Class Student <DataMember> _ Friend StudentName As String <DataMember> _ Friend StudentSurname As String <DataMember> _ Friend StudentNumber As Integer <DataMember> _ Friend StudentCourse As Integer End Class
Create an instance of the Student type.
C#
Student s = new Student(); s.StudentName = "Hannes"; s.StudentSurname = "du Preez"; s.StudentNumber = 123; s.StudentCourse = 5;
VB.NET
Student s = New Student() s.StudentName = "Hannes" s.StudentSurname = "du Preez" s.StudentNumber = 123 s.StudentCourse = 5
Use DataContractJsonSerializer to serialize the Student object to a memory stream.
C#
MemoryStream streamStudent = new MemoryStream(); DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(Student));
VB.NET
Dim streamStudent As New MemoryStream() Dim ser As New DataContractJsonSerializer(GetType(Student))
Write JSON data to the stream.
C#
ser.WriteObject(stream1, s);
VB.NET
ser.WriteObject(stream1, s)
Show output.
C#
streamStudent.Position = 0; StreamReader sr = new StreamReader(streamStudent); Console.WriteLine(sr.ReadToEnd());
VB.NET
streamStudent.Position = 0 StreamReader sr = New StreamReader(streamStudent) Console.WriteLine(sr.ReadToEnd())
Deserialize.
Use the ReadObject method of the DataContractJsonSerializer to deserialize the Student object.
C#
streamStudent.Position = 0; Student s2 = (Student)ser.ReadObject(streamStudent);
VB.NET
streamStudent.Position = 0 Student s2 = (Student)ser.ReadObject(streamStudent)
Show the results.
C#
Console.Write(s2.StudentName); Console.Write(s2.StudentSurname); Console.WriteLine(p2.StudentNumber); Console.WriteLine(p2.StudentCourse);
VB.NET
Console.Write(s2.StudentName) Console.Write(s2.StudentSurname) Console.WriteLine(p2.StudentNumber) Console.WriteLine(p2.StudentCourse)
Transport Layer Security (TLS) Support
Transport Layer Security (TLS) and its predecessor, Secure Sockets Layer (SSL), are cryptographic protocols that provide communications security over a computer network.
Create a new Console app in Visual Studio 2017 and enter the following. I am providing both C# and VB.NET versions:
C#
using System; using System.Collections; using System.Net; using System.Net.Security; using System.Net.Sockets; using System.Security.Authentication; using System.Text; using System.Security.Cryptography.X509Certificates; using System.IO; namespace Examples.System.Net { public class TCPClient { private static Hashtable CertErrs = new Hashtable(); public static bool Validate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors PolicyErrs) { if (PolicyErrs == SslPolicyErrors.None) return true; Console.WriteLine("Error: {0}", PolicyErrs); return false; } public static void CreateClient(string strMachineName, string strServerName) { // Create a TCP/IP client socket// TcpClient client = new TcpClient(strMachineName, 443); Console.WriteLine("Connected."); // Close the client's stream// SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback (Validate), null); try { sslStream.AuthenticateAsClient(strServerName); } catch (AuthenticationException e) { Console.WriteLine("Error: {0}", e.Message); Console.WriteLine ("Authentication failed."); client.Close(); return; } // Encode a test message into a byte array// byte[] bytArrMessage = Encoding.UTF8.GetBytes("Hello Hannes<END>"); sslStream.Write(bytArrMessage); sslStream.Flush(); string serverMessage = Read(sslStream); Console.WriteLine("Message: {0}", serverMessage); client.Close(); } static string Read(SslStream sslStream) { // Read the message// byte [] buffer = new byte[2048]; StringBuilder sbMessage = new StringBuilder(); int bytes = -1; do { bRead = sslStream.Read(buffer, 0, buffer.Length); Decoder decoder = Encoding.UTF8.GetDecoder(); char[] chars = new char[decoder.GetCharCount(buffer, 0, bRead)]; decoder.GetChars(buffer, 0, bytes, chars,0); sbMessage.Append (chars); if (sbMessage.ToString().IndexOf("<END>") != -1) { break; } } while (bytes != 0); return sbMessage.ToString(); } private static void Start() { Console.WriteLine("Enter Machine Name "); Environment.Exit(1); } public static int Main(string[] args) { string strServerCertName = null; string strMachineName = null; if (args == null || args.Length < 1 ) { Start(); } strMachineName = args[0]; if (args.Length < 2 ) { strServerCertName = strMachineName; } else { strServerCertName = args[1]; } TCPClient.CreateClient (strMachineName, strServerCertName); return 0; } } }
VB.NET
Imports System.Collections Imports System.Net Imports System.Net.Security Imports System.Net.Sockets Imports System.Security.Authentication Imports System.Text Imports System.Security.Cryptography.X509Certificates Imports System.IO Public Module TCPClient Private Shared CertErrs As New Hashtable() Public Shared Function Validate(sender As Object, _ certificate As X509Certificate, chain As X509Chain, _ PolicyErrs As SslPolicyErrors) As Boolean If PolicyErrs = SslPolicyErrors.None Then Return True End If Console.WriteLine("Error: {0}", PolicyErrs) Return False End Function Public Shared Sub CreateClient(strMachineName As String, _ strServerName As String) ' Create a TCP/IP client socket' Dim client As New TcpClient(strMachineName, 443) Console.WriteLine("Connected.") ' Close the clients stream' Dim sslStream As New SslStream(client.GetStream(), _ False, New RemoteCertificateValidationCallback _ (AddressOf Validate), Nothing) Try sslStream.AuthenticateAsClient(strServerName) Catch e As AuthenticationException Console.WriteLine("Error: {0}", e.Message) Console.WriteLine("Authentication failed.") client.Close() Return End Try ' Encode a test message into a byte array' Dim bytArrMessage As Byte() = Encoding.UTF8.GetBytes _ ("Hello Hannes<END>") sslStream.Write(bytArrMessage) sslStream.Flush() Dim serverMessage As String = Read(sslStream) Console.WriteLine("Message: {0}", serverMessage) client.Close() End Sub Private Shared Function Read(sslStream As SslStream) _ As String ' Read the message' Dim buffer As Byte() = New Byte(2047) {} Dim sbMessage As New StringBuilder() Dim bytes As Integer = -1 Do bRead = sslStream.Read(buffer, 0, buffer.Length) Dim decoder As Decoder = Encoding.UTF8.GetDecoder() Dim chars As Char() = New Char(decoder.GetCharCount _ (buffer, 0, bRead) - 1) {} decoder.GetChars(buffer, 0, bytes, chars, 0) sbMessage.Append(chars) If sbMessage.ToString().IndexOf("<END>") _ <> -1 Then Exit Do End If Loop While bytes <> 0 Return sbMessage.ToString() End Function Private Shared Sub Start() Console.WriteLine("Enter Machine Name ") Environment.[Exit](1) End Sub Public Shared Sub Main(args As String()) Dim strServerCertName As String = Nothing Dim strMachineName As String = Nothing If args Is Nothing OrElse args.Length < 1 Then Start() End If strMachineName = args(0) If args.Length < 2 Then strServerCertName = strMachineName Else strServerCertName = args(1) End If TCPClient.CreateClient(strMachineName, strServerCertName) Return 0 End Function End Module
Elliptic Curve Cryptography
Elliptic Curve Cryptography (ECC) is an extension to public key cryptography. In public key cryptography, two keys are used:
- A public key that everyone knows
- A private key that only you know
To encrypt, the public key is applied to the target by using a predefined operation that produces a pseudo-random number. To decrypt, the private key is applied to the pseudo-random number by using a different predefined operation. Usually, these operations are performed several times. The strength of public key cryptography lies in the fact that its algorithm knows that encryption is easy, and decryption is hard, thus making decryption impractical without the key.
With today’s technology and computers getting faster and more powerful by the day, there will come a time where the pseudo-prime cannot be made large enough to thwart an attack. That is where elliptic curve cryptography comes in. Elliptic curve cryptography uses the properties of an elliptical curve, the same pair of keys, and math to encrypt and decrypt the target information.
An elliptic curve is a graph that represents the points generated by the following equation:
y2 = x3 + ax + b
ImportParameters() methods were added to the ECDsa and ECDiffieHellman classes to allow for an object to represent an already established key. An ExportParameters() method also was added for exporting the key using explicit curve parameters.
Support for High-DPI Awareness Support in Windows Forms
High DPI (dots per inch) support improves the layout and appearance of forms and controls on high DPI monitors. You need to configure High DPI in your app’s Configuration file and you also need to add support for Windows 10 Compatibility in the Manifest file. High DPI (dots per inch) support is available only in applications that target the .NET Framework 4.7 as well as running on Windows 10 Creators Update onwards.
Add Windows 10 compatibility
Add the following code to your Manifest file:
<compatibility > <application> <!-- Windows 10 compatibility --> <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5- 48fd50a15a9a}" /> </application> </compatibility>
Add the High DPI support:
<System.Windows.Forms.ApplicationConfigurationSection> <add key="DpiAwareness" value="PerMonitorV2" /> </System.Windows.Forms.ApplicationConfigurationSection>
Lastly, call EnableVisualStyles in your program
C#
static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); }
VB.NET
Private Shared Sub Main() Application.EnableVisualStyles() Application.SetCompatibleTextRenderingDefault(False) Application.Run(New Form1()) End Sub
Conclusion
As time progresses, more and handier tricks to work with .NET Framework 4.7 come out. Now, let’s wait for the next .NET Framework!