Sunday, 16 September 2018

Creating a File Server using ASP.NET Core 2.1 Static Files Middleware

One of the coolest features of ASP.NET Core is the ability to serve static files on HTTP requests without any server-side processing. This means that you can leverage this technology to build your own file server to serve static files over the wire. I managed to code a quick solution over the weekend to be able to upload/download files to one of my servers easily with this technology.

It all started with this Tweet:

The issue here is that both of us spend loads of time taking pictures and videos of our daughter and end up sharing all this data via Whatsapp. By the end of the day we both have the same information but in different resolutions and qualities which makes our life quite difficult when trying to guess which picture has the highest quality for printing (we tend to print most of the pictures). So we needed something simpler and quicker where to store all this pictures and videos (keeping the highest possible quality) and that it would be easier for both of us to share.

.NET Core and Ngrok to the rescue. 

With Ngrok, I can easily expose one of my websites to the world via one of the ngrok tunnels. I do own a professional account with them and it really made my life much easier as I can expose whatever I need to the world without having to tinker with my router. This helps me to expose services from my Raspberry Pi's and from my Servers.

Using .NET Core Static files middleware, I was able to build a quick solution (accessible via any browser and mobile responsive) with just 300 lines of code.

The main features of the application are:
  • Multiple file uploader (up to 300 Mb).
  • Multiple file downloader.
  • Daily browsable functionality (it allows you to navigate on each day to see the list of files uploaded).
  • Thumbnail automatic generation using MagicScaler.
  • Automatic movie conversion via CloudConvert (this allows me to share videos between mobile devices as iPhones generate .mov files which cannot be played on Android devices).
  • Keep the existing quality of the file (full size). This means uploading huge files into the File server.
  • Cookie authentication with Policies.

You can see the flow in the image below:

Sample code for the file uploader can be found below:

To list the files, I use the File provider in ASP.NET Core which uses the static file middleware to locate static files, in my case pictures and videos.

There are quite a lot of things to do to improve the application but now anyone who uses the application can easily upload/download pictures from one of my servers which is monitored and constantly backed up so no picture gets lost. Also segregating pictures by dates helps a lot to find the one you were looking for.

I'm really impressed with the latest release of .NET Core (note that this has been built with .NET Core 2.1 and there is already a 2.2 preview version available) as the request are really fast and you can't even notice any lag even browsing with your phone on 3G which gives a nice user experience.

This is how it looks when browsing from my phone:

Source code will be available soon on my Github page as I'm trying to figure out one of the issues with https redirection which still does not work correctly and without it, it doesn't make sense.

Jordi Corbilla

Sunday, 1 July 2018

Configure TeamCity to access private GitHub Repositories

One of the challenges I have been facing lately after moving to private repositories on GitHub is the ability to access them via TeamCity. The issue is that now the repository is not accessible via https and you have to find an alternative to retrieve the source code of your repository securely.

For this task, I will show you how to use GitHub Deploy keys and how to configure TeamCity to interact with your private repository.

The overall idea can be seen in the figure above. First, we will have to create the keys so we can place them in the required section. To generate the keys, you can just use Git Bash and using the command below:

Once finished, you will have two keys, the private and the public one.

Installing the public key in GitHub:

The operation above should've produced 2 keys (files):

  • id_rsa (private key)
  • (public key)

Open the file or run the following command on your git bash console to copy the content of the file into the clipboard: clip < ~/.ssh/

Now, go to your private repository on GitHub and select "Settings" and then "Deploy Keys". Once there, click on "Add deploy key" and paste the content of the file you've opened before / copied into the clipboard.

Once completed, you should see something like the image below (note that the image below shows that the key has been already used):

Installing the private key in TeamCity:

The following operations have been done to the latest version of TeamCity at the time of the publication of this article (2018.1 build 58245). I tried version 2017 initially and the configuration didn't work (just so you know if you are still on any version prior to 2018.1):

Click on your project overview and click on "Edit project Settings". Select "SSH Keys" and click "Upload SSH Key" button to upload your id_rsa file:

Now the SSH key will be available in your VCS Root. Now go to your build step and add a Git VCS Root that will pull the source code from the repository. The parameters that you have to configure are as follow:

  • VCS Root Name: Name of your VCS.
  • Fetch URL: URL of your repository in format git (not in https format as it will not be available because the repository is private). In this case you will have to change the https URL by this other git one as shown in the sample below:
  • Default branch: refs/heads/master
  • Authentication method: Uploaded Key
  • Username: empty (don't type anything here)
  • Uploaded Key: id_rsa (is the one that I've just uploaded)
  • Password: type the secret word you have configured in your private key if any.

If you now test the connection, it should be successful:

If you have a look at your project, you will see that the project is successfully connecting to your repository and pulling out the changes that are pending to be implemented in your pipeline:

I hope you find it useful as I have spent quite a lot of time just trying to find the right approach.


Sunday, 15 April 2018

Detecting Ajax Requests In ASP.NET MVC 5

Security is one of my major concerns nowadays and it is quite common that someone will try to browse to a particular URL given any chance. To avoid this, we can detect whether the request came from an Ajax request or from a normal browser request.

Within ASP.NET MVC5 applications is quite easy to check if a request is being made via AJAX through the extension named IsAjaxRequest() method that is available on the Request object. The IsAjaxRequest() actually works by simply performing a check for the X-Requested-With header.

The example below will show you how wrap this functionality inside an Action Filter so you can add this feature to any controller you want to perform this check upon.

Creating the Action Filter:

Then just use the attribute in any of the actions you want to perform this operation:

And now, if you try to browse that action from a normal request you will get the following error:

Now you can make your site more secure without worrying about someone inadvertently clicking to  the action.