300% performance increase on #MySQL inserts in C#

This may be obvious to anybody who frequently uses MySQL in C#, but for someone who’s come from the SQL Server world, you may quickly realise that the connection pool management is not done as well in MySQL as it is in SQL Server. I guess it is something lacking in the MySQL connector.

Anyway, long story short – if your code for inserts in mysql is as follows (pseudocode:)

Foreach(item in collection)

{

Open Connection

Run SQL

Close Connection

}

Then you can have a huge (300%) performance increase by doing the following:

Open Connection

Foreach (item in collection)

{

Run SQL

}

Close Connection

It’s pretty obvious, but you don’t have to do this sort of refactoring with the SQL Server driver, since the connection pool is managed under-the-hood.

Categories: Uncategorized

Designing a .NET application with removable features

Normally, if you remove a class file from an application, it will just break, but let’s imagine, you want to allow that, so that, a sysops engineer can delete sensitive code from your application that may not be required in a given circumstance.

So, to design an application that will allow you to just delete a file without breaking the application, takes alot of forethought, and here’s one possible way of doing it.

TL;DR; here’s the github repo: https://github.com/infiniteloopltd/PluginDemo

So, First off, I’ll describe this proof of concept application. It has two features, Addition and Subtraction, which are named Addition.cs and Subtraction.cs in the Features folder. Either of these files can be deleted, and it won’t break the application, but evidently the ability to perform that operation will be removed.

So, First, I define an Interface, which features must adhere to; as follows;

namespace PluginDemo
{
    public interface IFeature
    {
        string Description { get; }

        int Execute(int a, int b);
    }
}

So, each feature has a Description, and it can perform some numerical operation on two numbers. Here is how Addition.cs implements this interface;

namespace PluginDemo
{
    class Addition : IFeature
    {
        public string Description
        {
            get
            {
                return "Addition";
            }
        }

        public int Execute(int a, int b)
        {
            return a + b;
        }
    }
}

Now, the magic is in the reflection, where we generate a dynamic list at runtime of all classes in the assembly that implement IFeature. (except IFeature itself), which is defined in a class named FeatureManager

using System;
using System.Collections.Generic;
using System.Reflection;

namespace PluginDemo
{
    public static class FeatureManager
    {
        private static readonly List<IFeature> _features = new List<IFeature>();

        static FeatureManager()
        {
            var dll = Assembly.GetExecutingAssembly();
            foreach (var type in dll.GetTypes())
            {
                if (typeof(IFeature).IsAssignableFrom(type) && !type.IsInterface)
                {
                    _features.Add(Activator.CreateInstance(type) as IFeature);
                }
            }
        }

        public static List<IFeature> Features
        {
            get
            {
                return _features;
            }
        }
    }
}

Now, we can list all available features by calling;

foreach (var feature in FeatureManager.Features)
{
   Console.WriteLine(feature.Description);
}

And, we can use this feature list to check for the availability of a feature, and call it, if it is available.

var addition = FeatureManager.Features.FirstOrDefault(f => f.Description == "Addition");
if (addition != null)
{
  Console.WriteLine("1 + 2 = " + addition.Execute(1,2) );
}

Here, as you can see in the above code. If the file, Addition.cs is deleted, then the addition object is null, but no exception is thrown.

Categories: Uncategorized

Print a #PDF from C# using #Spire.NET

There are many ways to print a PDF in C#, but I wanted one that was unobtrusive, and didn’t depend on any particular software being installed on the client machine. – So I’m using Spire.NET

TL DR; Here is the github repo: https://github.com/infiniteloopltd/PrintPDF

I am also using a image printer driver called Joy Image Printer (http://www.joyprinter.com/) – which enables me to test this, witout wasting paper. The output image has watermarking, so it’s not for production, just testing. It’s also unobtrusive, and doesn’t pop up any windows.

So, the first step is that I wanted to list all the printers installed on the client machine, and allow the user select one by number. Then it loads a static PDF into Spire, and calls the print method. The Free version of Spire (https://www.e-iceblue.com/Introduce/pdf-for-net-introduce.html) is limited to 10 pages, but that was fine for my purposes.

var iSelection = 1;
Console.WriteLine(“Which printer do you wish to use:”);
foreach (string printer in PrinterSettings.InstalledPrinters)
{
Console.WriteLine(iSelection + “:” + printer);
iSelection++;
}
iSelection = Convert.ToInt16(Console.ReadLine());
var printerName = PrinterSettings.InstalledPrinters[–iSelection];
// Install-Package Spire.PDF -Version 6.7.6
// http://www.joyprinter.com/index.html — handy for development
var document = new PdfDocument();
document.LoadFromFile(“hello-world.pdf”);
document.PrintSettings.PrinterName = printerName;
document.Print();
document.Dispose();

Categories: Uncategorized

Apply for a #LetsEncrypt #SSL cert for an #NGINX server

Self-signed certs suck. They aren’t secure, and throw nasty security error messages when people access your website.

Let’s encrypt offers real, verifiable SSL certs, that give you that nice padlock in the URL, and most imporantly, they are perfectly secure. So, if you have NGINX running on Linux, here is how you get a SSL cert, and apply it to your server.

So, step 1; is to install the getssl tool, which you can do as follows;

curl --silent https://raw.githubusercontent.com/srvrco/getssl/master/getssl > getssl ; chmod 700 getssl

Step 2, is create a config file for the domain

./getssl -c domain.com

Edit the config file using the pico editor (or other)

pico .getssl/domain.com/getssl.cfg

Make the following changes:


Uncomment CA="https://acme-v02.api.letsencrypt.org"
Edit the ACL line to say:
ACL=('/home/wwwroot/.well-known/acme-challenge')

By uncommenting the line CA=”https://acme-v02.api.letsencrypt.org&#8221; it means that you are using the live API, not the sandbox (Fake LE Intermediate and Root X1) CA.

The ACL must point to the location on disk where the root of your website is.

Then create the acme-challenge folder as follows

cd /home/wwwroot
mkdir .well-known
cd .well-known/
mkdir acme-challenge

Then apply for the cert as follows;

sudo ./getssl -d domain.com

Assuming that step ran completely, copy the retrieved cert and key to the nginx folder;

cd .getssl
cd domain.com/

sudo cp *.crt /etc/nginx/
sudo cp *.key /etc/nginx/

sudo nginx -s reload

The NGINX config should resemble the following:

server {

    listen 443;

    ssl_certificate           /etc/nginx/domain.crt;
    ssl_certificate_key       /etc/nginx/domain.key;

    ssl on;
    ssl_session_cache  builtin:1000  shared:SSL:10m;
    ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
    ssl_prefer_server_ciphers on;

    access_log            /var/log/nginx/domain.access.log;
    location / {
       ...
    }
}
Categories: Uncategorized

Using #Postgres from .NET Core

This little “Hello World” of Postgres is a simple application in .NET that accesses the CRT.SH certifiate database to list all known Certificate Authorities.

The CRT.SH database is open to all clients thanks to Sectigo.

TL;DR; Here is the Github repo https://github.com/infiniteloopltd/HelloWorldPostgres2

using System;
using Npgsql; // Install-Package Npgsql -Version 4.1.3.1

namespace HelloPostgres
{
    class Program
    {
        static void Main(string[] args)
        {
            const string connString = "Host=crt.sh;Username=guest;Password=certwatch;Database=certwatch";
            var conn = new NpgsqlConnection(connString);
            conn.Open();
            // List all certificate authorities
            var cmd = new NpgsqlCommand("select name from ca", conn);
            var reader = cmd.ExecuteReader();
            while (reader.Read())
            {
                Console.WriteLine(reader["name"]);
            }   
            conn.Close();
            Console.ReadLine();
        }
    }
}

Categories: Uncategorized

Record events to #DataDog with .NET Core / C#

Datadog is a powerful logging tool, great for keeping an eye on servers that may not always have a pretty admin tool.

Here is a code example in C# on how to record an event to DataDog via it’s API. Here I have used my own API Key, (feel free to mess about, I don’t intend to use this account seriously), but evidently, you should get your own API key.

TL;DR – Getting ot the point, here is the Github repo if you don’t want to read – https://github.com/infiniteloopltd/DataDogCSharpCore

Here is the code I used;

 const string key = "f15d23159b008e325e2cf65a04502c05";
var url = "https://api.datadoghq.eu/api/v1/events?api_key=" + key; // EU api endpoint
var oReq = new
{
	text= "This is the event body",
	title = "This is the event title"
};
var strReq = JsonConvert.SerializeObject(oReq);
var wc = new WebClient();


try
{
	var response = wc.UploadString(url, strReq);
	Console.WriteLine(response);
}
catch (WebException wex)
{
	var err = new StreamReader(wex.Response.GetResponseStream()).ReadToEnd();
	Console.WriteLine(err);
}
Categories: Uncategorized

Assign a static IP to an #AWS #lambda function

To assign a static ip to Lambda function for outbound requests we need to deploy the lambda function in private subnet of a VPC which will be attach with a NAT gateway. As NAT Gateway is associated with an Elastic IP address so all the traffic from lambda function will be routed via this EIP.

Creating VPC: VPC is a virtual private cloud which consists of below components.

  1. CIDR block – Range of IP address which you VPC can have. It is defined like 10.0.0.0/16.

 For more information on cidr please refer this link : https://www.ionos.com/digitalguide/server/know-how/cidr-classless-inter-domain-routing/

  1. Subnets – A subnet, or subnetwork, is a segmented piece of a larger network. More specifically, subnets are a logical partition of an IP network into multiple, smaller network segments.

In this solution we have divided our VPC to one public subnet and one private subnet. Based on our requirement we can create multiple public and private subnets in our VPC.

  1. Route Tables: Each subnet is associated with a route table which defines the inbound and outbound traffic in that subnet.
  1. Internet Gateway: Public VPCs are the one which are accessible from Internet and to have connectivity from Internet each public subnet attached with an Internet Gateway.
  1. NAT Gateway: Private Gateways are the one which are not accessible from Internet. We keep our secure servers like Databases, application servers in our private subnet which do not need to directly expose to Internet. But these servers need to send outbound request to Internet for some scenarios like downloading the latest os or security patches. To allow Private subnet to send outbound traffic we need to attach a NAT gateway to Private subnet. This NAT Gateway need to be created in public subnet.
A close up of a map

Description automatically generated

Steps to create VPC:

To calculate CIDR for VPC and subnets you can use this site : https://mxtoolbox.com/subnetcalculator.aspx

A screenshot of a computer

Description automatically generated

This will create a VPC with CIDR range 20.0.0.0/16 and one public subnet with cidr 20.0.1.0/24.

A screenshot of a social media post

Description automatically generated

Once your VPC created with a public subnet you will see 2 route tables will be created automatically. One is default and one is attached to your public subnet. You can see which subnet is associated to your route table in details.

A screenshot of a social media post

Description automatically generated

Now give your route table proper name so that you can easily identify them.

If you click on your public route table and see Routes then you will see route from 0.0.0.0/0 to internet gateway. This internet Gateway was automatically created while creating the VPC.

If anytime this internet gateway is not created the you can create it from console and attach it to the route table with same configuration as below.

A screenshot of a computer screen

Description automatically generated
A screenshot of a social media post

Description automatically generated

Now as your VPC is created and a public subnet is created, we will create a private subnet.

Goto Subnets- > Create subnet- >enter details.

A screenshot of a social media post

Description automatically generated
A screenshot of a social media post

Description automatically generated

Now your two subnets are available as below:

A screenshot of a social media post

Description automatically generated

Now to we need to create a NAT Gateway and attach it to our private subnet. We must have an Elastic IP created in our account to create a NAT Gateway.

Important Note: NAT Gateway should always be created in a public subnet so that It can have access to Internet.

A screenshot of a cell phone

Description automatically generated
A screenshot of a social media post

Description automatically generated
A screenshot of a social media post

Description automatically generated

Once your NAT gateway is created, you need to attach it to your private subnet by adding a route in your private route table.

A screenshot of a computer

Description automatically generated

Click on Edit routes and add a route from 0.0.0.0/0 to your NAT Gateway and save.

A screenshot of a cell phone

Description automatically generated
A screenshot of a social media post

Description automatically generated

Once your route is created now associate your private subnet to this route table.

Goto Subnet Associations – > edit subnet associations-> select your subnet.

A screenshot of a social media post

Description automatically generated
A screenshot of a cell phone

Description automatically generated
A screenshot of a cell phone

Description automatically generated
A screenshot of a social media post

Description automatically generated

Now your VPC is ready with one public subnet and one private subnet.

Create a Lambda execution role for your VPC:

Now you need to create an IAM for your VPC to execute your lambda.

Goto IAM Roles-> create new role- >

For Select type of trusted entity, confirm that AWS service is selected.
For Choose a use case, choose Lambda.

A screenshot of a computer

Description automatically generated

Choose Next: Permissions.

Under Attach permissions policies, search for AWSLambdaVPCAccessExecutionRole. Select the policy with that name. If you lambda need any other permissions then select them and add to your role.

A screenshot of a cell phone

Description automatically generated

Move your lambda to VPC private subnet:

Change Lambda execution role to newley created role.

A screenshot of a computer screen

Description automatically generated

Click Edit

A screenshot of a cell phone

Description automatically generated

Now go to the VPC section of Lambda and edit to point to your VPC and private subnet.

A screenshot of a social media post

Description automatically generated
A screenshot of a cell phone

Description automatically generated
A screenshot of a cell phone

Description automatically generated
A screenshot of a social media post

Description automatically generated

All done and now your lambda will send outbound from EIP of your NAT Gateway.

Categories: Uncategorized

Run an ASP.NET website on #AWS without a server

Here is a a few simple steps to run a ASP.NET (Razor / C#) based website on AWS without provisioning an EC2 instance – So you only pay for the few seconds when your website is being requested, and some S3 storage.

TL;DR; Here is the github repo https://github.com/infiniteloopltd/AWSServerlessHelloWorld

First, you have to download the AWS Toolkit for Visual Studio and then open up VS 2019, and select New Project > AWS Serverless application (.NET Core)

Right click on the Project, select publish. Press the user icon, and enter in your AWS Access key and Secret from IAM.

Then, enter in a cloud formation name (just type anything), and create a new S3 bucket (again, any name). Press publish, and wait 5 minutes.

At the end you’ll be given a url like this;

https://ok4xp67po9.execute-api.eu-west-1.amazonaws.com/Prod

Categories: Uncategorized

Start and Stop an #AWS #EC2 instance using the C# SDK

Automation of EC2 instances is really important if you want to optimize costs. Perhaps you have a server that does not need to be online 100% of the time, perhaps just during peak hours, or perhaps, when running a scheduled task.

You can use C# to query the state of an instance, and start and stop it. You will need to generate your own Access keys in AWS IAM, and the instance ID and region will change based on your setup,

Add the Nuget Package AWSSDK.EC2

Here is the code to log in to AWS

const string accessKey = "....";
const string secretKey = ".....";
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
var config = new AmazonEC2Config
{
RegionEndpoint = Amazon.RegionEndpoint.GetBySystemName("eu-west-2")
};
var client = new AmazonEC2Client(credentials, config);
var response = client.DescribeInstanceStatus(new DescribeInstanceStatusRequest { IncludeAllInstances = true});
var state = response.InstanceStatuses.First(i => i.InstanceId == "i-0fb....").InstanceState.Name.ToString();
Console.WriteLine("Instance is " + state);

then to start the instance it’s :

client.StartInstances(new StartInstancesRequest(new List<string> { "i-0fb9f4....." }));

And to stop the instance it’s:

  client.StopInstances(new StopInstancesRequest(new List<string> {"i-0fb9....."}));

Easy done!

Categories: Uncategorized

Car Registration #API for #Israel

Israel is a country with 2.9 Million vehicles, and a population of 8.8 million, giving a total car ownership percentage of 33%.

We have just launched an API in Israel, that allows uses to search for a vehicle by license plate (Registration Number), and will return technical details about that vehicle.

This API can be used to determine, the make, model, VIN, and other technical specifications of a vehicle registered in Israel from it’s registration number (license plate). The API applies to cars, motorbikes, and heavy vehicles.

The website is available in Hebrew here ; http://www.rechevapi.co.il/ but, equally, the API can be accessed via any of our other websites, such as here; https://carregistrationapi.com/api/reg.asmx – using the same account, and credits.

Here is an excerpt from our documentation:

Israel support

Offline data available
Car registration plates in Israel use the /CheckIsrael  endpoint and return the following information:

  • Make / Model
  • Age
  • VIN number
  • Fuel
  • Engine size
  • Representative image

Sample Registration Number: 

1011928

Sample Json:

{

  “Description”: “Porsche CAYENNE”,

  “Variant”: “PLATINUM”,

  “RegistrationYear”: 2017,

  “CarMake”: {

    “CurrentTextValue”: “Porsche”

  },

  “CarModel”: {

    “CurrentTextValue”: “CAYENNE”

  },

  “MakeDescription”: {

    “CurrentTextValue”: “Porsche”

  },

  “ModelDescription”: {

    “CurrentTextValue”: “CAYENNE”

  },

  “VehicleIdentificationNumber”: “WP1ZZZ92ZHLA32339”,

  “Fuel”: “Diesel”,

  “EngineSize”: “2967”,

  “Co2”: “179”,

  “HorsePower”: “262”,

  “IsAutomatic”: “1”,

  “Doors”: “5”,

  “Seats”: “5”,

  “Weight”: “2870”,

  “EngineCode”: “CVVA”,

  “VehicleUse”: “P”,

  “TestDate”: “02/01/2020 00:00:00”,

  “LicenseDate”: “11/01/2021 00:00:00”,

  “MakeHebrew”: “פורשה גרמניה”,

  “VehicleType”: “Car”,

  “ImageUrl”: “http://rechevapi.co.il/image.aspx/@UG9yc2NoZSBDQVlFTk5F&#8221;

}

Categories: Uncategorized