Monday, October 30, 2017

ASP.NET Core MVC + Web API app with EF Core 2.0 & SQLite

This tutorial uses Visual Studio 2017 and ASP.NET Core 2.0. 

My intention is to give you a practical introduction into developing ASP.NET Core 2.0 MVC and Web API apps with the SQLite database as an alternative to traditional SQL Server.

A useful utility that comes in handy when working with the SQLite database is SQLiteStudio. Download SQLiteStudio from: http://sqlitestudio.pl/?act=download. Extract the ZIP file and place contents in a separate folder. Run SQLiteStudio.exe.

We will build an ASP.NET Core 2.0 app that uses the following Student entity:
image_thumb1

ASP.NET Core 2.0 MVC project

In a working directory, create a folder named SQLiteWeb. Change to the SQLiteWeb directory. Try out some of these important .NET Core 2.0 commands:





  1. dotnet --help – this gives you a list of common commands
  2. dotnet restore – restore dependencies specified in the .NET project
  3. dotnet build - Builds a .NET project
  4. dotnet run --help – provides help information about the run command
  5. dotnet new --help – shows the types of templates that can be scaffolded. At the time of writing these are 18 different templates
  6. dotnet new mvc --help – shows switches that can be used when creating an MVC application
We will create an MVC application that uses "Individual authentication" and the SQLite database. 
Execute the following terminal command from within the SQLiteWeb directory: 

dotnet new mvc --auth Individual


A web app is created for you and all Nuget packages are automatically restored. To run the application, 
execute the following command inside the terminal window:

dotnet run

Notice a message similar to the following:

Hosting environment: Production
Content root path: E:\_DEMO\SQLiteWeb
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.



As described in the message, point your browser to http://localhost:5000 and you will see the default 
ASP.NET Core page:


image

This runs your application in a web server called Kestrel that is listening on port 5000. Register a new user.

Stop the web server by hitting Ctrl+C. If you are curious about where the data is saved and the location of the SQLite database, you will find a *.db file located in the bin/Debug/netcoreapp2.0 directory. Have a peek at its contents using the SQLiteStudio utility mentioned earlier in this article.

To open your web application in Visual Studio, start Visual Studio then open the SQLiteWeb.csproj file.

File >> Open >> Project Solution


Hit CTRL + F5 in Visual Studio 2017. This time, the web application will start and will be hosted by IIS Express

When working with ASP.NET Core, you will need to go to the command-line interface frequently. Add a command-prompt extension to make it easier. Click on Tools >> Extensions and Updates

image

Find an extension named “Open Command Line” as shown below.

image

If you have not installed it already, install the above extension.

In solution explorer, right-click on the SQLiteWeb node the choose “Open Command Line” >> “Default (cmd)

image

This opens a regular operating system terminal window. 

The Student class

Inside of the Models folder, add a class file named Student.cs. Use the following code for the class file:

public class Student {
  public int StudentId { get; set; }
  public string FirstName { get; set; }
  public string LastName { get; set; }
  public string School { get; set; }
  public DateTime StartDate { get; set; }
}


Add the following property to the ApplicationDbContext.cs class file located in the Data directory.

  public DbSet<Student> Students { get; set; }

Notice the connection string in the appsettings.json file:


{
   "ConnectionStrings": {
      "DefaultConnection": "DataSource=app.db"
   },
   "Logging": {
      "IncludeScopes": false,
      "LogLevel": {
         "Default": "Warning"
      }
   }
}

Migrations

We are now ready to do some migrations: 
  • Compile your application
  • Open a command terminal inside the  main project SQLiteWeb folder
  • Add a migration to the project with the following ef command:
dotnet ef migrations add "First Migration"

Notice that class files are created in the Data/Migrations folder.
  • We will then update the database with the following terminal command:
dotnet ef database update
You will experience the following error:

SQLite does not support this migration operation ('AddForeignKeyOperation'). For more information, see http://go.microsoft.com/fwlink/?LinkId=723262.

This error is caused by the fact the SQLite cannot alter tables and indexes during migration. See this article. The workaround is to comment out all the lines of code in the "Data/Migrations/xxxxxx_First Migration.cs" file that do not pertain to the Students entity. This should be done in both the up() and down() methods. Thereafter, run the "dotnet ef database update" command again and it should complete successfully.

Seed Data

Before we carry out code first migrations, let us first create some seed data: 
  • In the Models folder, create a class named DummyData.cs.
  • Add the following Initialize() method code inside the DummyData class:
public static void Initialize(ApplicationDbContext db) {
  if (!db.Students.Any()) {
    db.Students.Add(new Student {
      FirstName = "Bob",
      LastName = "Doe",
      School = "Engineering",
      StartDate = Convert.ToDateTime("2015/09/09")
    });
    db.Students.Add(new Student {
      FirstName = "Ann",
      LastName = "Lee",
      School = "Medicine",
      StartDate = Convert.ToDateTime("2014/09/09")
    });
    db.Students.Add(new Student {
      FirstName = "Sue",
      LastName = "Douglas",
      School = "Pharmacy",
      StartDate = Convert.ToDateTime("2016/01/01")
    });
    db.Students.Add(new Student {
      FirstName = "Tom",
      LastName = "Brown",
      School = "Business",
      StartDate = Convert.ToDateTime("2015/09/09")
    });
    db.Students.Add(new Student {
      FirstName = "Joe",
      LastName = "Mason",
      School = "Health",
      StartDate = Convert.ToDateTime("2015/01/01")
    });
    db.SaveChanges();
  }
}

To generate seed data, we will first inject the dependency “ApplicationDbContext context” into the arguments of the Configure() method in Startup.cs. 
Next, we can make a call to seed the data at the bottom of the Configure() method with the following statement:
      
DummyData.Initialize(context);

At this point, data will not have been seeded yet because this happens when the application is actually run.

Creating an MVC UI

Let us seed the data by running your web application in a browser. You should see the same page as we saw earlier. Let us create a UI so that we can see the seeded data.

  • Right-click on the Controllers folder and choose Add >> New Item… >> Controller...
  • Choose "MVC Controller with views, using Entity Framework" then click on Add.
  • Model Class=Student, Data context class=ApplicationDbContext
Click on Add. If you are asked to save the solution file then accept the default location and save it in your project root folder.


You’ll notice that the controller takes a ApplicationDbContext as a constructor parameter. ASP.NET dependency injection will take care of passing an instance of ApplicationDbContext into your controller.

The controller contains an Index action, which displays all students in the database, and a Create action, which inserts a new student into the database.

  • Let us add a link to the Students controller on the main page of our application. Open _Layout.cshtml under Views/Shared.
  • Paste the following markup in the navigation section around line 36:

<li><a asp-area="" asp-controller="Students" asp-action="Index">Students</a></li>


  • Run the application then click on the Students link. You should see the dummy data that we created.

image

  • Add a new student to the database.


The WebAPI Controller


Let us add a Web API Studentsapi controller to our projects. 
  • Right-click on the Controllers folder >> Add > Controller...
  • Select "API Controller with actions, using Entity Framework" then click Add.
  • Model class=Student, Data context class=ApplicationDbContext, Controller name=StudentsapiController
  • Click on Add
  • Hit CTRL-F5 on your keyboard and point your browser to /api/studentapi. You will see the seed data appearing as JSON in the browser:
image_thumb11

Saturday, October 28, 2017

Deploying web apps to Azure using Git

In previous posts, I showed two ways (GitHub & FTP) of deploying web apps to Azure. See the following articles:

Continuous deployment of ASP.NET MVC 5 app to Azure thru GitHub
http://blog.medhat.ca/2016/10/connecting-to-azure-website-with-ftp.html

In this post, I will show you how to deploy a PHP web app to Azure by directly using the Git repository that resides in Azure itself.
The following are prerequisites:
In this example, I am using a PHP app that simply shows some cartoon characters. The output of the PHP app looks like this:

image

Login into portal.azure.com. On the left-side, click on “App Services”.

image

Click on “+ Add”.

image

Click on “Web app”.

image

On the next blade, click on the “Create” button.

image

Enter a unique name for App name. Choose your subscription, select to create a new Resource Group, select an App Service plan/Location then click on Create.

image

The web application will be created for you in less than two minutes. When it is ready, you will see it in the list of your App services.

image

Click on the newly created app service on the first blade. In the above example it is toon. Then, click on Deployment credentials.

image

Enter a unique FTP/deployment username and Password. Note that these credentials can be used for both FTP and Git. Also, these same credentials can be used for this web app as well as other web apps that you may have already created or those that you plan to create in the future. Therefore, it important that you remember these credentials. If you forget the credentials, then you can always create a new pair of username and password.

image

Our next step is to let Azure know that we want to deploy our web app using Git. Click on “Deployment options”.

image

Click on “Choose Source” then select “Local Git Repository”.

image

Afterwards, click on OK.

image

Next, we need to obtain the URL of the remote Git repository on Azure. Click on Overview.

image

Copy the “Git clone url” and save it in a text editor like Notepad. This will later be used to push your code from your computer to Azure. Note that you can conveniently click on a toolbar on the right of the Git URL to copy it.

image

Now, back on your computer, open a terminal window in the working directory of the web application that you wish to deploy. Run the following Git commands:
git init
git add .
git commit –m “first commit”
git remote add azure {the url of the remote Azure Git repository}
git push azure master
Right after you execute the last push command, you will be prompted to authenticate with your deployment credentials in Azure. These are the credentials that you created earlier.

image

Once your credentials are accepted, the push process will commence. When it is all finished, you can verify that your code was accepted by Azure by clicking on “Deployment options” in Azure.You should see a check mark beside your commit.

image

The true test is to go to the website and see whether or not it indeed works. Click on Overview. The website URL is on the right side of the last blade. Click on it.

image

The website should show up in your browser.

image

What next? Make a change to your code and push it to the remote Git repository on Azure. You will soon after notice that the change you made is reflected on your web application.

Thanks for coming this far in my article.

Wednesday, March 29, 2017

Build an ASP.NET Core 1.1 tag helper that consumes Azure Web API RESTful service

In a previous post, I demonstrated how to create an ASP.NET Core 1.0 tag helper. Since ASP.NET 1.1 was released, some of the packages in the previous post are not supported anymore. Therefore, I am hereby updating this article to fix this issue. I am also using Visual Studio 2017 instead of Visual Studio 2015.

Tag Helpers in ASP.NET Core allow you to create your own tags that fulfill a server-side purpose. In this tutorial, I will show you how to create a tag helper <toon> that accesses a Web API service and displays contents in any razor view page.

The Web API service we will consume in this exercise is located at http://cartoonapi.azurewebsites.net/api/cartoon. It delivers the names of cartoon characters and their respective images.

1) To start with, create an ASP.NET Core Web application named ToonTagHelper in Visual Studio 2017.

2) We need to create a class that closely matches the nature of the Web API JSON object. Therefore, add the following Toon class to a Models folder in your project:
public class Toon {
  public string Name { get; set; }
  public string PictureUrl { get; set; }
}
3) Next, we need to install the We API Client libraries. To that end, execute the following commands from within the Package Manager Console window in Visual Studio 2017:
Install-Package Newtonsoft.Json
Install-Package System.Net.Http
Install-Package System.Runtime.Serialization.Xml
Alternatively, you can run the following commands from within a terminal window:
dotnet add package Newtonsoft.Json
dotnet add package System.Net.Http
dotnet add package System.Runtime.Serialization.Xml

This should add the following dependencies to your project.json file:
<PackageReference Include="Newtonsoft.Json" Version="10.0.1" />
<PackageReference Include="System.Net.Http" Version="4.3.1" />
<PackageReference Include="System.Runtime.Serialization.Xml" Version="4.3.0" />
4) Add the following tag to the bottom of Views/Home/About.cshtml:


<toon></toon>

5) Create a folder named TagHelpers and add to it a class file named ToonTag.cs. Have the class inherit from TagHelper and implement the ProcessAsync() method as follows:

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
}


We could have implemented a method Process() instead. However, in our case, it is appropriate to implement ProcessAsync() instead because we are about to make an async call to a remote service.

6) Add the following instance variable to the ToonTagHelper class:
 private string baseUrl = "http://cartoonapi.azurewebsites.net";

7) Annotate the CartoonCharactersTagHelper class with the following:

[HtmlTargetElement("toon")]
[HtmlTargetElement(Attributes = "toon")]


The first annotation defines the tag <toon> and the second defines the “toon” attribute. This means that we have two different ways to produce the same output on a razor .cshtml view.

8) Add the following method to the ToonTagHelper class:

async Task<IEnumerable<Toon>> GetToonsAsync() {
  HttpClient client = new HttpClient();
  client.BaseAddress = new Uri(baseUrl);
  client.DefaultRequestHeaders.Accept.Clear();
  client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
  IEnumerable<Toon> toons = null;
  try {
    // Get all cartoon characters
    HttpResponseMessage response = await client.GetAsync("/api/cartoon");
    if (response.IsSuccessStatusCode)
    {
       string json = await response.Content.ReadAsStringAsync();
      toons = JsonConvert.DeserializeObject<IEnumerable<Toon>>(json);
    }
  } catch (Exception e) {
      System.Diagnostics.Debug.WriteLine(e.ToString());
  }
  return toons;
}



The above code makes a request to the Web API service and returns an IEnumerable<Toon> collection with the results.

9) Add the following code inside the ProcessAsync() method:

IEnumerable<Toon> toons= await GetToonsAsync();
string html = string.Empty;
html += "<table><tr><th>Name</th><th>Picture</th></tr>";
foreach (var item in toons) {
    string photoUrl = baseUrl + "/" + item.PictureUrl;
    html += "<tr>";
    html += "<td>" + item.Name + "</td>";
    html += "<td><img src='" + photoUrl + "' style='width: 50px' /></td>";
    html += "</tr>";
}
html += "</table>";
output.Content.SetHtmlContent(html);


The above code creates a table with the collection of cartoon characters so that it can be displayed wherever the tag helper is used.

11) Register the tag name in the Views/_ViewImports.cshtml file by adding the following to the list of tags that are already there:

@addTagHelper "ToonTagHelper.TagHelpers.ToonTag, ToonTagHelper"

You may need to adjust the above names depending on what you called your app and/or your tag helper class.

11) Compile and run your application, then click on About. You should see the following output:



If you inspect the table in your browser, you will see the following:



The above is using the tag and not the attribute. Edit About.cshtml and comment out “<toon></toon>” and put the following <div> tag with the toon attribute underneath it:
<div toon></div>

Your About.cshtml should now look like this:
@{
    ViewData["Title"] = "About";
}
<h2>@ViewData["Title"].</h2>
<h3>@ViewData["Message"]</h3>

<p>Use this area to provide additional information.</p>
@*<toon></toon>*@
<div toon></div>
When you run your application. you should see the same output as before. However, upon inspection of the HTML source, you will notice that a <div> tag is the primary container for our code rather than a <toon> tag:



This proves to us that you can either use tags or attributes with TagHelpers in ASP.NET Core.