File Upload in ASP.NET Core

In one of the .NET Core trainings I was conducting recently, one of my students asked about uploading files using .NET Core application. Here's a solution. When we use ASP.NET MVC to upload a file, we use the HttpPostedFileBase class. This class is used to access the files uploaded by the client in an MVC application. In .NET Core, the IFromFile interface is used to represent a file that is sent with the HttpRequest. In this article we will use the IFromFile interface to upload the file. We will use Visual Studio 2017 and .NET Core 2.1. Information about the IFromFile interface can be read from this link.

Step 1: Open Visual Studio 2017 and create a new ASP.NET Core Web Application. Name this application as Core_FileUpload. Select the MVC project with .NET Core and ASP.NET Core 2.1 version for the project as shown in the following image:


mvc-app[8]

Step 2: In the project, add a new folder and name this folder as UploadedFiles. This folder will be used to store uploaded files. Step 3: In the Models folder, add a new class file. Name this file as FileManager.cs. In this file, add the following code

using Microsoft.AspNetCore.Http;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Core_FileUpload.Models
{
public class FileManager
{
    public async Task UploadFile(IFormFile file)
    {
        try
        {
            bool isCopied = false;
            //1 check if the file length is greater than 0 bytes 
            if (file.Length > 0)
            {
                string fileName = file.FileName;
                //2 Get the extension of the file
                string extension = Path.GetExtension(fileName);
                //3 check the file extension as png
                if (extension == ".png" || extension == ".jpg")
                {
                    //4 set the path where file will be copied
                    string filePath = Path.GetFullPath(
                        Path.Combine(Directory.GetCurrentDirectory(), 
                                                    "UploadedFiles"));
                    //5 copy the file to the path
                    using (var fileStream = new FileStream(
                        Path.Combine(filePath, fileName), 
                                       FileMode.Create))
                    {
                        await file.CopyToAsync(fileStream);
                        isCopied = true;
                    }
                }
                else
                {
                    throw new Exception("File must be either .png or .JPG");
                }
            }
            return isCopied;
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
}
}


The above code has following specifications. The UploadFile method accepts IFromFile interface. Note that the numbering below matches with the number in the comments applied on the code above.

  1. Check the file length if it is greater than 0. If the file size is greater than 0 then only the uploaded file will be further processed.
  2. Since we are restricting the file upload for .png and .jpg files, this step reads an extension of the file using Path.GetExtension() method. This method accepts the file name of which is read using FileName property of IFromFile interface.
  3. If the file extension is .png or .jpg, only  then will the file  used for uploading else the code will throw an exception.
  4. This code set the path for the UploadedFiles folder, to copy uploaded files in this folder.
  5. This code uploads the file in the UploadedFiles folder using CopyToAsync() method of the IFromFile interface.
Step 4: Since we will perform error handling in our application, lets change ErrorViewModel class from the Models class by adding the following properties:

public string ErrorMessage { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
Step 5: Change the Error.cshtml file from the Shared sub-folder of Views folder as shown in the following markup:

<h2>@Model.ErrorMessage</h2>
<hr />
<div>
    <a asp-action="@Model.Action" asp-controller="@Model.Controller">
        Go Back
    </a>
</div>
Step 6: In the Controllers folder add a new empty MVC controller. Name this controller as FileUploadController. Add the following code in this controller:

using Core_FileUpload.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;
namespace Core_FileUpload.Controllers
{
    public class FileUploadController : Controller
    {
        FileManager fileManager;
        public FileUploadController()
        {
            fileManager = new FileManager();
        }
        public IActionResult Index()
        {
            return View("Index");
        }

        [HttpPost]
        public async  Task UploadFile(IFormFile file)
        {
            try
            {
                bool uploadSuccess = await fileManager.UploadFile(file);
                ViewBag.Message = "File Uploaded Successfully";
                return View("Index");
            }
            catch (Exception ex)
            {
                return View("Error", new ErrorViewModel() 
                                    {ErrorMessage= ex.Message });
            }
        }
    }
}

The controller class uses FileManager class created in Step 3. The Index action method of the controller class returns Index view. The UploadFile() action method accepts the IFromFile interface as a parameter and pass it to the UploadFile() method of the FileManager class. The UploadFile() method of the controller is executed for each HttpPost request. Step 7: Scaffold an Index view from the Index action method by right-clicking in the method and selecting Add View option. Select View template as empty view without model as shown in the following image:  index-view[7] 

Add the following markup in the Index.cshtml

@{
    ViewData["Title"] = "Index";
}

<h2>Uploading File in ASP.NET Core using 
    <strong>IFormFile</strong> Interface
</h2>
<form method="post" enctype="multipart/form-data" 
      asp-controller="FileUpload" asp-action="UploadFile">
    <div class="form-group">
        <div class="col-md-10">
            <p>Upload Image File (.png):</p>
            <input type="file" name="file"/>
        </div>
    </div>
    <hr />
    <div class="form-group">
        <div class="col-md-10">
            <input type="submit" value="Upload File" />
        </div>
    </div>
    <hr />
    <div class="form-group">
        <span>@ViewBag.Message</span>
    </div>
</form>
The above markup uses Html <form> tag. The form will be posted to UploadFile action method of the FileUpload controller. The enctype value multipart/form-data means the file will be send using POST request. Step 8: Modify the Configure() method of the StartUp.cs file for setting default route for FileUploadController as shown in the following code

app.UseMvc(routes =>
    {
        routes.MapRoute(
            name: "default",
            template: "{controller=FileUpload}/{action=Index}/{id?}");
    });

Run the application, and it will display the following result:

 run-page[6]

Click on the Choose File button, this will open the File Open window. Select .png or .Jpg file from the windows. Once the file is selected, click on the Upload File button, the file will be uploaded in the UploadedFiles folder as shown in the following image: uploaded-files[3]

If you select a file other than .png or .jpg, an error page will be displayed as shown in the following image :

 error[4]

Conclusion: The IFromFile interface can be used to read and access uploaded files using HttpRequest in an ASP.NET Core application.

Using CSS Selection Pseudo-element to change the Default Selection Style of your WebPage

CSS Pseduo-elements allow you to style certain parts of a document. In this article, we will see how to change the default selection style of your web page contents using ::Selection PseudoElement.

Although you can use any webeditor of your choice, I am using Visual Studio 2013 for this demonstration. Let’s start by creating a new ASP.NET Web application. Start Visual Studio and click on New Project. Choose the Web Category and choose ASP.NET Web Application as shown below –

crtwebapp

HTML5 Picture Element for Responsive Images

In this article, we will look at the <picture> element and how it helps in responsive design to render images of different sizes, based on the physical device accessing the content.

To display an image in our HTML pages, we have so far made use of the <img/> element with the source [src] attribute. Here’s an example:

<img src="Images/default.png" alt="Default Logo" />

With varying screen sizes and pixels, handling this image becomes a challenge. Let's create a small example for demonstrating this. I am using the free Visual Studio Community Edition although you can use any other web editor of your choice. Create an empty web application and add a HTML page with the name TestPicture.html in our project. Add the following code:

Login failed for user IIS APPPOOL\AppPool4.5 or APPPOOL\ASP.NET

The error ‘Login failed for user 'IIS APPPOOL\AppPool4.5’ usually occurs when you configure a new website in IIS or move an existing website to a newer version of IIS.

A simple solution to the error is to add a login to SQL Server for IIS APPPOOL\ASP.NET v4.5 and grant appropriate permission to the database.

Open SQL Server Management Studio > Right click ‘Security’ > New > Login

iis-apppool-login

Action Filters in ASP.NET MVC

Continuing with our MVC 101 series today we look at an important MVC feature, Filters. Filters in ASP.NET MVC are a way to apply cross-cutting logic at the controller level. Some examples of cross-cutting logic is Security and Logging.

Security is a cross cutting concern because, once enabled, we need to apply it for all incoming requests in the web Application. Imagine a world where you don’t have filters, in such case for every request that comes in, you Action method in controller will have to check if the user was Authorized to perform the action and view its result.

This not only violates single responsibility principle of the Action Method (it’s doing two things, evaluating security and computing the Action’s output) but is also an extremely verbose and repetitive work that we’ve to do irrespective of what the Action is supposed to do. Moreover, writing Authentication Code in action method cannot be guaranteed. There is no certainty that a developer may or may not miss out on implementing the code!

C# (Csharp) Switch Case Statement with Example

A C# switch case statement defines multiple groups of statements, and then executes one of these statement; depending on the value of a constant or test expression.

Let us understand this concept with an example.

string siteName = "DevCurry";
switch (siteName) {
    case "DotNetCurry":
    Console.WriteLine("This website is DotNetCurry.com");
    break;

    case "DevCurry":
    Console.WriteLine("This website is DevCurry.com");
    break;

    default:
    Console.WriteLine("Default Website");
}

As you can see, we start by defining a constant at the top:

Remove Vertical Scrollbars in SyntaxHighlighter

SyntaxHighlighter created by Alex Gorbatchev is a code syntax highlighter developed in JavaScript. It basically makes your code snippets beautiful.

Many a times even when not required, a vertical scroll gets added to your code as shown here:

syntax-highlighter-scroll

The scroll appears in some browsers (especially Chrome) as the default style set in shCoreDefault.css is overflow: auto. If you do not want a vertical scrollbar, you can always do this:

Getting Started with NUnit in ASP.NET MVC

Visual Studio 2012 comes with a perfectly capable Unit Testing system in MS Test. However if your team’s skills require you to use alternate Testing frameworks like NUnit, Visual Studio is game to play along. In this article, we’ll see the how we can setup NUnit to work with Visual Studio’s Test Explorer and run Unit tests in our project.

Setting up NUnit

There are two parts to NUnit setup for use in Visual Studio. First part is to install the framework, we can do this in two ways.

1. Download the 2.6.2 (latest at the time of writing) msi installer from http://www.nunit.org. Ensure Visual Studio is not running while the installer is running. This installs NUnit globally along with the NUnit test runner. However the test runner needs .NET 3.5 to run.

2. Another way to include NUnit in your project is to download it using the following Nuget Package Manager command

PM> install-package NUnit

Second part is to setup the NUnit Test Adapter so that Visual Studio recognizes the Test Cases in our project and allows us to Run them from the Test Explorer.