<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brent</title>
    <description>The latest articles on DEV Community by Brent (@brentokta).</description>
    <link>https://dev.to/brentokta</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F69566%2Fe1f4e3b2-d154-4e8a-bb62-cf2541ff3353.png</url>
      <title>DEV Community: Brent</title>
      <link>https://dev.to/brentokta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/brentokta"/>
    <language>en</language>
    <item>
      <title>Build a CRUD App with ASP.NET Core 2.2 and Entity Framework Core</title>
      <dc:creator>Brent</dc:creator>
      <pubDate>Wed, 03 Apr 2019 05:00:00 +0000</pubDate>
      <link>https://dev.to/oktadev/build-a-crud-app-with-asp-net-core-2-2-and-entity-framework-core-1pe9</link>
      <guid>https://dev.to/oktadev/build-a-crud-app-with-asp-net-core-2-2-and-entity-framework-core-1pe9</guid>
      <description>&lt;p&gt;If you’re like me, you love music. Music is always streaming somewhere in my house at all times. I especially like going to see live music, but it can be hard to know where and when live music is happening. LiveMusicFinder is a web application that allows users to enter when and where some live music is going down. This beta version is &lt;strong&gt;very&lt;/strong&gt; rough, but I will show you how I built it with ASP.NET Core 2.2 and Entity Framework Core.&lt;/p&gt;

&lt;p&gt;ASP.NET Core 2.2 is a cross-platform version of Microsoft’s ASP.NET Framework that run on any platform. For example, I’ll be developing this on an Ubuntu laptop using Visual Studio Code. I’ll also be using Entity Framework ore for interacting with the data store. Entity Framework Core is the easiest way by far for .NET developers to interact with a database which, for expedience sake, will be SQLite, a super light-weight database. Let’s get to it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaffold an ASP.NET Core 2.2 Web Application
&lt;/h2&gt;

&lt;p&gt;Start by creating the base application. In a terminal shell run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new mvc &lt;span class="nt"&gt;-n&lt;/span&gt; LiveMusicFinder

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will scaffold an ASP.NET Core 2.2 MVC application in a folder called &lt;code&gt;LiveMusicFinder&lt;/code&gt;, and that will be the main namespace you’ll be working in.&lt;/p&gt;

&lt;p&gt;Just open that folder in Visual Studio Code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;LiveMusicFinder
code &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be prompted to add some missing assets. This is the &lt;code&gt;.vscode&lt;/code&gt; folder that allows you to launch and debug the application with &lt;strong&gt;F5&lt;/strong&gt;, just click the &lt;strong&gt;Yes&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fadd-vscode-folder-3b18881d1e0018b69fc250d85b035ec041462c76ca7af8b558a25b204fea2182.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fadd-vscode-folder-3b18881d1e0018b69fc250d85b035ec041462c76ca7af8b558a25b204fea2182.png" alt="Add .vscode folder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you’ve developed in ASP.NET Core before, there are significant changes to the look and feel of the base application in .NET Core 2.2, so fire it up and check it out!&lt;/p&gt;

&lt;p&gt;You may see a screen come up that tells you that your connection is not private. This is because, in the latest .NET Core, the development application runs over &lt;code&gt;https&lt;/code&gt;, but you don’t have a certificate for &lt;code&gt;localhost&lt;/code&gt;. You could either get a local certificate, which is fairly easy to do, or you can proceed. It won’t warn you every time, so for now, just click the &lt;strong&gt;Advanced&lt;/strong&gt; button and click &lt;strong&gt;Proceed to localhost (unsafe)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fnot-private-advanced-b3245243b35b8b3ead4b3beea765a51b91d212fd7ee53fcf75b6d25073399b0d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fnot-private-advanced-b3245243b35b8b3ead4b3beea765a51b91d212fd7ee53fcf75b6d25073399b0d.png" alt="Not Private Advanced"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you can see the new design of the base application in .NET!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fnew-app-running-be09a3cea33c2ce6fc3982305ecd19a4f10c459681a7ae4bbd2ab577886e0d23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fnew-app-running-be09a3cea33c2ce6fc3982305ecd19a4f10c459681a7ae4bbd2ab577886e0d23.png" alt="New App Running"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I &lt;em&gt;know&lt;/em&gt;, right? No big images in a carousel. No chunks of text with links to the .NET Documentation. It’s really sparse. That’s a great thing. Now you won’t have to start by deleting images and content from the application before you can start building!&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Entity Framework Core Classes to Your ASP.NET Core 2.2 Application
&lt;/h2&gt;

&lt;p&gt;Now that you have a solid foundation, start by adding the model that you’ll use for live music shows. In the &lt;code&gt;Models&lt;/code&gt; folder, add a class called “LiveShow”.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;LiveMusicFinder.Models&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LiveShow&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Artist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Venue&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;ShowDate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;EnteredBy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class is pretty straight-forward and certainly could use some more details in the future, but for now, it has everything you need: Who is playing? Where are they paying? and When is the show?&lt;/p&gt;

&lt;p&gt;Next, you’ll need a database context to save the shows to the database. For simplicity’s sake, just use a SQLite database. When the application goes live, it will be easy to change the connection to a more “production-appropriate” database.&lt;/p&gt;

&lt;p&gt;Before you can use SQLite, you’ll need the Entity Framework NuGet package for connecting to it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Microsoft.EntityFrameworkCore.SQLite &lt;span class="nt"&gt;-v&lt;/span&gt; 2.2.3

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you’re ready to create the database context for SQLite. Create a folder called &lt;code&gt;Data&lt;/code&gt; in the root of the project and add a class file called &lt;code&gt;ApplicationDbContext.cs&lt;/code&gt; with the following contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;LiveMusicFinder.Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.EntityFrameworkCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;LiveMusicFinder.Data&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ApplicationDbContext&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;DbContext&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DbContextOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;base&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DbSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LiveShow&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;LiveShows&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This brings in the &lt;code&gt;LiveMusicFinder.Models&lt;/code&gt; namespace, so you can reference the &lt;code&gt;LiveShow&lt;/code&gt; model class. It derives from &lt;code&gt;Microsoft.EntityFrameworkCore&lt;/code&gt;’s &lt;code&gt;DbContext&lt;/code&gt; and passes all appropriate options to the base class. The public handle for the &lt;code&gt;LiveShows&lt;/code&gt; collection in the database is the &lt;code&gt;DbSet&amp;lt;LiveShow&amp;gt;&lt;/code&gt; property. Now all you have to do is tell the application to inject this context into any class that needs it by adding it to the &lt;code&gt;Startup.cs&lt;/code&gt; class. In the &lt;code&gt;ConfigureServices()&lt;/code&gt; method, just before the &lt;code&gt;SetCompatibilityVersion()&lt;/code&gt; call, add the line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSqlite&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Data Source=LiveMusicFinder.db"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll need to add two &lt;code&gt;using&lt;/code&gt; statements to your &lt;code&gt;Startup.cs&lt;/code&gt; file. You &lt;em&gt;could&lt;/em&gt; just paste the line above in and then put your cursor on the &lt;code&gt;ApplicationDbContext&lt;/code&gt; type and use &lt;code&gt;CTRL+.&lt;/code&gt; to see the menu item that will add the &lt;code&gt;LiveMusicFinder.Data&lt;/code&gt; namespace &lt;code&gt;using&lt;/code&gt; statement and do the same with the &lt;code&gt;UseSqlite()&lt;/code&gt; method that needs &lt;code&gt;Microsoft.EntityFrameworkCore&lt;/code&gt;, or you can just cut and paste them from here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;LiveMusicFinder.Data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.EntityFrameworkCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will inject the newly created context into our controllers and make it easy to work with the database and to change it later for production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scaffold the Entity Framework Core Controller for Live Shows in Your ASP.NET 2.2 Application
&lt;/h2&gt;

&lt;p&gt;To make life easier, and so you don’t have to write all the actions for the controller by hand, you’ll use the &lt;code&gt;dotnet&lt;/code&gt; CLI and scaffold a controller. This could be done in Visual Studio 2017/2019 by navigating the &lt;strong&gt;File&lt;/strong&gt; &amp;gt; &lt;strong&gt;New&lt;/strong&gt; menus and options. You can also just run two commands. The first command will install the code generator templates.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Microsoft.VisualStudio.Web.CodeGeneration.Design

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just use those templates to generate a data controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet aspnet-codegenerator controller &lt;span class="nt"&gt;-name&lt;/span&gt; LiveShowsController &lt;span class="nt"&gt;-async&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; LiveMusicFinder.Models.LiveShow &lt;span class="nt"&gt;-dc&lt;/span&gt; LiveMusicFinder.Data.ApplicationDbContext &lt;span class="nt"&gt;-namespace&lt;/span&gt; Controllers &lt;span class="nt"&gt;-outDir&lt;/span&gt; Controllers &lt;span class="nt"&gt;-udl&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now there’s a lot to unpack here, and as you use these templates in the future, it’s helpful to know that &lt;code&gt;dotnet aspnet-codegenerator controller --help&lt;/code&gt; exists to help you figure out which switches you need.&lt;/p&gt;

&lt;p&gt;The command above told the &lt;code&gt;aspnet-codegenerator&lt;/code&gt; tool that you want to use the &lt;code&gt;controller&lt;/code&gt; code generator, that you wanted to call it &lt;code&gt;LiveShowsController&lt;/code&gt;, and that you want the action methods to be asynchronous (with the &lt;code&gt;-async&lt;/code&gt; switch). You also told the generator that the controller will be a data controller and that it will use the &lt;code&gt;LiveMusicFinder.Models.LiveShow&lt;/code&gt; model and the &lt;code&gt;LiveMusicFinder.Data.ApplicationDbContext&lt;/code&gt; database context for database interaction. The next couple of switches are really housekeeping for the generator: what namespace the controller will go in and what folder the generated controller will go in. The final switch deals with the views that will be generated (Yes! This generated views to go with the controller actions!!). The &lt;code&gt;-udl&lt;/code&gt; switch tells the view generators to “Use the Default Layout” for the views it generates. Sweet, huh?&lt;/p&gt;

&lt;p&gt;Once you’ve run the commmand, you should see a new folder in the &lt;code&gt;Views&lt;/code&gt; directory called &lt;code&gt;LiveShows&lt;/code&gt; (to match the controller). Inside that folder should be five new views! One for each of the different ways to “view” the &lt;code&gt;LiveShow&lt;/code&gt; model: &lt;code&gt;Create.cshtml&lt;/code&gt;, &lt;code&gt;Delete.cshtml&lt;/code&gt;, &lt;code&gt;Details.cshtml&lt;/code&gt;, &lt;code&gt;Edit.cshtml&lt;/code&gt;, and &lt;code&gt;Index.cshtml&lt;/code&gt; (the listing).&lt;/p&gt;

&lt;p&gt;You’ll also have the &lt;code&gt;LiveShowsController&lt;/code&gt; in the &lt;code&gt;Controllers&lt;/code&gt; directory with &lt;code&gt;ApplicationDbContext&lt;/code&gt; injected through the constructor and actions for each of the views already wired up to list, create, update, and delete &lt;code&gt;LiveShow&lt;/code&gt; objects! You could run it, and it’s all wired up!&lt;/p&gt;

&lt;p&gt;Now you just need a menu item to get you to the &lt;code&gt;Index&lt;/code&gt; view. In the &lt;code&gt;_Layout.cshtml&lt;/code&gt; file in &lt;code&gt;Views/Shared&lt;/code&gt;, add a menu item to the &lt;code&gt;ul&lt;/code&gt; with the &lt;code&gt;navbar-nav&lt;/code&gt; class on it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link text-dark"&lt;/span&gt; &lt;span class="na"&gt;asp-area=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;asp-controller=&lt;/span&gt;&lt;span class="s"&gt;"LiveShows"&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Index"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Live Shows&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I usually just copy one of the other menu items and change the controller, action, and menu item text.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can now run your application and click on the &lt;strong&gt;Live Shows&lt;/strong&gt; menu item, and it will take you to the list of live shows.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fdatabase-error-message-b080d5633a215b70f836c06a8b93d9de82cb2bf27353a46f5ced3b3e11b014c9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fdatabase-error-message-b080d5633a215b70f836c06a8b93d9de82cb2bf27353a46f5ced3b3e11b014c9.png" alt="Database Error Message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But Houston, we have a problem. If you actually try and run it right now, it will fail. The error message is &lt;em&gt;almost&lt;/em&gt; helpful. It tells you that the “LiveShows” table doesn’t exist, but the &lt;em&gt;real&lt;/em&gt; problem is that the database doesn’t actually exist yet. To get your application to ensure that it exists when you run it, add the database context to the &lt;code&gt;Configure()&lt;/code&gt; method of your &lt;code&gt;Startup.cs&lt;/code&gt; and tell it to ensure that the database is created.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IApplicationBuilder&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IHostingEnvironment&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApplicationDbContext&lt;/span&gt; &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;dbContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnsureCreated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="c1"&gt;// ...the rest of the method&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you fire up the app this time, everything would be working!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fdata-app-working-1ef1f31c96c8ade17dcd9ef3621ba90e0e2ce9358f7ca70f89de538a566dcb34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fdata-app-working-1ef1f31c96c8ade17dcd9ef3621ba90e0e2ce9358f7ca70f89de538a566dcb34.png" alt="Data App Working"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While this is an okay start, anyone can not only enter shows but edit anyone else’s. And since the form allows users to enter their own name in the &lt;strong&gt;EnteredBy&lt;/strong&gt; field, there’s really no set way to track people’s submissions. You need authentication! But friends don’t let friends write auth. They use &lt;a href="https://developer.okta.com" rel="noopener noreferrer"&gt;Okta&lt;/a&gt;!&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding Authentication to Your ASP.NET Core 2.2 Application
&lt;/h2&gt;

&lt;p&gt;Why &lt;em&gt;wouldn’t&lt;/em&gt; you write the authentication piece yourself? The login screen is the thing that fools most developers into thinking that authentication will be easy. Then they realize they need a “forgot password?” email workflow and user management screens. Not to mention if you ever need multi-factor authentication. Just don’t do that to yourself. Use a provider. &lt;a href="https://developer.okta.com" rel="noopener noreferrer"&gt;Okta&lt;/a&gt; makes authentication simple to add, and it has all those features already built-in! You can get your free-forever developer account &lt;a href="https://developer.okta.com/signup/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once you’ve signed up, go to your dashboard and take note of your &lt;strong&gt;Org URL&lt;/strong&gt; on the right side of the screen just below the pink &lt;strong&gt;Upgrade&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fokta-org-url-6b1fce3aeb309d0d36fa0bd6d5a7b29013b0b658c476d09ff9bdfd2413dd5b7a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fokta-org-url-6b1fce3aeb309d0d36fa0bd6d5a7b29013b0b658c476d09ff9bdfd2413dd5b7a.png" alt="Okta Org URL"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the &lt;strong&gt;Applications&lt;/strong&gt; menu and click &lt;strong&gt;Add Application&lt;/strong&gt; to add a new application. Choose &lt;strong&gt;Web&lt;/strong&gt; as the platform for your application, then click &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the &lt;strong&gt;Application Settings&lt;/strong&gt; page name, it “Live Music Finder” and set the ports for the &lt;strong&gt;Base URIs&lt;/strong&gt; and &lt;strong&gt;Login redirect URIs&lt;/strong&gt; to &lt;code&gt;5001&lt;/code&gt; and change the scheme to &lt;code&gt;https&lt;/code&gt;. You can leave everything else at the default values. and click &lt;strong&gt;Done&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fokta-app-settings-df4aac8282386ab1c29ae23b8fc15c198320c330546515e282de28b5368242b8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fokta-app-settings-df4aac8282386ab1c29ae23b8fc15c198320c330546515e282de28b5368242b8.png" alt="Okta App Settings"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you’re done, you will see a &lt;strong&gt;General Settings&lt;/strong&gt; tab for your app. On that tab click the &lt;strong&gt;Edit&lt;/strong&gt; button and add a &lt;strong&gt;Logout redirect URIs&lt;/strong&gt; entry as &lt;code&gt;https://localhost:5001/signout/callback&lt;/code&gt;. That is the URL that the middleware will handle when the logout from Okta occurs.&lt;/p&gt;

&lt;p&gt;Copy your &lt;strong&gt;Client ID&lt;/strong&gt; and &lt;strong&gt;Client Secret&lt;/strong&gt; from the &lt;strong&gt;Client Credentials&lt;/strong&gt; section of the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure Authentication in Your ASP.NET Core 2.2 Application
&lt;/h2&gt;

&lt;p&gt;The next portion is back in your code. You’ll need the Okta ASP.NET SDK. You can install it by running the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Okta.AspNetCore &lt;span class="nt"&gt;--version&lt;/span&gt; 1.1.5

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;appsettings.json&lt;/code&gt; file so that the final version looks like below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Logging"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"LogLevel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Default"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Warning"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Okta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ClientId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{yourClientId}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ClientSecret"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"{yourCliientSecret}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"OktaDomain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://{yourOktaDomain}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"PostLogoutRedirectUri"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://localhost:5001/"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"AllowedHosts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Back in your &lt;code&gt;Startup.cs&lt;/code&gt; you’ll need some &lt;code&gt;using&lt;/code&gt; statements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Okta.AspNetCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Authentication.Cookies&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the very top of the &lt;code&gt;ConfigureServices()&lt;/code&gt; method, add the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;oktaMvcOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;OktaMvcOptions&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="n"&gt;Configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Okta"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oktaMvcOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;oktaMvcOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Scope&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;"openid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"profile"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="n"&gt;oktaMvcOptions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetClaimsFromUserInfoEndpoint&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAuthentication&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultAuthenticateScheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CookieAuthenticationDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultSignInScheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;CookieAuthenticationDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DefaultChallengeScheme&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;OktaDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MvcAuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddCookie&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddOktaMvc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;oktaMvcOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While this &lt;em&gt;looks&lt;/em&gt; complex, it’s really quite simple. First, it just creates a new &lt;code&gt;OktaMvcOptions()&lt;/code&gt; object. Then it binds all those &lt;code&gt;appsettings.json&lt;/code&gt; settings you just created. The options then have the list of scopes you want to get back when someone authenticates, and sets the boolean value for &lt;code&gt;GetClaimsFromUserInfoEndpoint&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt;. This just tells the middleware that you want to use the OIDC endpoint for figuring out what the URL is for getting user information.&lt;/p&gt;

&lt;p&gt;The next section is actually setting up the middleware to add authentication (with some options for setting cookies, etc.) and to use the Okta SDK for authentication with our configured options.&lt;/p&gt;

&lt;p&gt;You’ve &lt;em&gt;configured&lt;/em&gt; the service, but you still need to tell the application to use this service that you’ve just configured. In the &lt;code&gt;Configure()&lt;/code&gt; method, add one line of code right before the &lt;code&gt;UseMvc()&lt;/code&gt; line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseAuthentication&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now authentication is wired up, you just need to add some user interface elements to trigger login and logout.&lt;/p&gt;

&lt;p&gt;Add a new file to the &lt;code&gt;Controllers&lt;/code&gt; folder called &lt;code&gt;AccountController.cs&lt;/code&gt; with the following contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Authentication.Cookies&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Mvc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Okta.AspNetCore&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;LiveMusicFinder.Controllers&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccountController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Login&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(!&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;IsAuthenticated&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Challenge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;OktaDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MvcAuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;RedirectToAction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Index"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Home"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IActionResult&lt;/span&gt; &lt;span class="nf"&gt;Logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SignOutResult&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;OktaDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MvcAuthenticationScheme&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;CookieAuthenticationDefaults&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AuthenticationScheme&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Login()&lt;/code&gt; method just checks to see if the user is already logged in. If they aren’t, it calls &lt;code&gt;Challenge()&lt;/code&gt; which will redirect to an Okta-hosted login page for them to authenticate. Once they’ve successfully logged in, the action will redirect to the home page.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Logout()&lt;/code&gt; action will call the log out endpoint in Okta with some scheme options set. Once that is done, Okta will redirect to that &lt;code&gt;/signout/callback&lt;/code&gt; endpoint that the OIDC middleware handles, and the user will be redirected to the URL in the &lt;code&gt;PostLogoutRedirectUri&lt;/code&gt; setting from the application’s configuration.&lt;/p&gt;

&lt;p&gt;The only thing left is adding login and log out buttons to the user interface. To do that, create a partial view in &lt;code&gt;Views/Shared&lt;/code&gt; called &lt;code&gt;_LoginPartial.cshtml&lt;/code&gt; with the following contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;@if (User.Identity.IsAuthenticated)
{
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-text"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Hello, @User.Identity.Name&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;  
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"document.getElementById('logout_form').submit();"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"cursor: pointer;"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Log out&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;asp-controller=&lt;/span&gt;&lt;span class="s"&gt;"Account"&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Logout"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"logout_form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
}
else
{
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&amp;gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-controller=&lt;/span&gt;&lt;span class="s"&gt;"Account"&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Login"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Log in&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This just checks if the user is logged in and shows the appropriate buttons.&lt;/p&gt;

&lt;p&gt;Add this partial to the &lt;code&gt;_Layout.cshtml&lt;/code&gt; file after the existing navigation so that the whole navigation section looks like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-collapse collapse justify-content-between"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"navbar-nav mr-auto"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link text-dark"&lt;/span&gt; &lt;span class="na"&gt;asp-area=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;asp-controller=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Index"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link text-dark"&lt;/span&gt; &lt;span class="na"&gt;asp-area=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;asp-controller=&lt;/span&gt;&lt;span class="s"&gt;"Home"&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Privacy"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Privacy&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-item"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"nav-link text-dark"&lt;/span&gt; &lt;span class="na"&gt;asp-area=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;asp-controller=&lt;/span&gt;&lt;span class="s"&gt;"LiveShows"&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Index"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Live Shows&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;partial&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"_LoginPartial"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Notice that some of the classes have changed. This is to push the authentication menu to the right while leaving the regular navigation items where they are.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Well? What’re you waiting for? Fire that puppy up and bask in the glory of authentication!!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fapp-with-auth-9cfa9a81d419e85d52d4c55edb8a74b6a2ed033b82c009918805b4638a238669.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fapp-with-auth-9cfa9a81d419e85d52d4c55edb8a74b6a2ed033b82c009918805b4638a238669.png" alt="App With Auth"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There’s still one thing left to fix. Right now, users still enter their own name in the &lt;strong&gt;EnteredBy&lt;/strong&gt; field, and anyone can edit or delete anyone else’s posts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add Authorization to Your ASP.NET Core 2.2 Application
&lt;/h2&gt;

&lt;p&gt;First things first, add the &lt;code&gt;[Authorize]&lt;/code&gt; attribute to every action on &lt;code&gt;LiveShowsController&lt;/code&gt; &lt;strong&gt;except&lt;/strong&gt; the &lt;code&gt;Index&lt;/code&gt; and &lt;code&gt;Details&lt;/code&gt; actions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: This will require a &lt;code&gt;using&lt;/code&gt; statement for &lt;code&gt;Microsoft.AspNetCore.Authorization&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Change the &lt;code&gt;Edit&lt;/code&gt; and the &lt;code&gt;Create&lt;/code&gt; views to not ask the user for their name. Remove the &lt;strong&gt;EnteredBy&lt;/strong&gt; form groups of both files. You can get it in the controller when they’ve logged in and add it there. In the &lt;code&gt;LiveShowsController&lt;/code&gt; change the &lt;code&gt;Create()&lt;/code&gt; method by removing the &lt;code&gt;EnteredBy&lt;/code&gt; from the &lt;code&gt;Bind&lt;/code&gt; list in the method signature, then add the following line to the beginning of the &lt;code&gt;Create()&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;liveShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnteredBy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;Edit()&lt;/code&gt; method, change the code &lt;strong&gt;inside the &lt;code&gt;try&lt;/code&gt; block&lt;/strong&gt; to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;existingShow&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LiveShows&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FindAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;existingShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnteredBy&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Identity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Unauthorized&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;existingShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Artist&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;liveShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Artist&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;existingShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Venue&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;liveShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Venue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;existingShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowDate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;liveShow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ShowDate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;existingShow&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SaveChangesAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This just gets the existing show in the database with the associated ID and makes sure the logged-in user is the one who entered it. If not, it just returns a &lt;code&gt;401 Unauthorized&lt;/code&gt; response. If the current user &lt;em&gt;does&lt;/em&gt; own the record, it just updates all the values in the existing show and saves the changes. Everything else in the method stays the same.&lt;/p&gt;

&lt;p&gt;Lastly, change the &lt;code&gt;Index&lt;/code&gt; and &lt;code&gt;Details&lt;/code&gt; views to hide edit and delete buttons for users that are &lt;em&gt;not&lt;/em&gt; the owner of that show. In the &lt;code&gt;Index&lt;/code&gt; view, change the last &lt;code&gt;td&lt;/code&gt; in the view to this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Details"&lt;/span&gt; &lt;span class="na"&gt;asp-route-id=&lt;/span&gt;&lt;span class="s"&gt;"@item.Id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Details&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  @if (User.Identity.IsAuthenticated &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; item.EnteredBy == User.Identity.Name)
  {
    &lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt; |&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Edit"&lt;/span&gt; &lt;span class="na"&gt;asp-route-id=&lt;/span&gt;&lt;span class="s"&gt;"@item.Id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Edit&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;span&amp;gt;&lt;/span&gt; |&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Delete"&lt;/span&gt; &lt;span class="na"&gt;asp-route-id=&lt;/span&gt;&lt;span class="s"&gt;"@item.Id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  }
&lt;span class="nt"&gt;&amp;lt;/td&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;Details&lt;/code&gt; view do the same thing by changing the ending &lt;code&gt;div&lt;/code&gt; to this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
  @if (User.Identity.IsAuthenticated &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; Model.EnteredBy == User.Identity.Name)
  {
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Edit"&lt;/span&gt; &lt;span class="na"&gt;asp-route-id=&lt;/span&gt;&lt;span class="s"&gt;"@Model.Id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Edit&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;span&amp;gt;&lt;/span&gt; |&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Delete"&lt;/span&gt; &lt;span class="na"&gt;asp-route-id=&lt;/span&gt;&lt;span class="s"&gt;"@Model.Id"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Delete&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&amp;lt;span&amp;gt;&lt;/span&gt; |&lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
  }
  &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;asp-action=&lt;/span&gt;&lt;span class="s"&gt;"Index"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Back to List&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you’re ready to rock like Beethoven! Fire the app up one more time and confirm that you can only change and delete your own records. Ain’t it cool?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fapp-final-running-ca07b9117804f76fa1df7ca7f275510c1048ab96ab041cabdc851e69fb4ea8d7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdeveloper.okta.com%2Fassets-jekyll%2Fblog%2Faspnet22-crud%2Fapp-final-running-ca07b9117804f76fa1df7ca7f275510c1048ab96ab041cabdc851e69fb4ea8d7.png" alt="Final App Running"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Taking Your ASP.NET Core Skills to the Next Level
&lt;/h2&gt;

&lt;p&gt;If you want to learn more about ASP.NET Core, check out some of the other great content on our blog!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.okta.com/blog/2019/03/26/build-a-crud-app-with-aspnetcore-and-typescript" rel="noopener noreferrer"&gt;Build a CRUD App with ASP.NET Core and Typescript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.okta.com/blog/2019/03/21/build-secure-microservices-with-aspnet-core" rel="noopener noreferrer"&gt;Build Secure Microservices with AWS Lambda and ASP.NET Core&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.okta.com/blog/2019/02/07/build-your-first-azure-function-visual-studio-code" rel="noopener noreferrer"&gt;Build Your First Azure Function in Visual Studio Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As always, leave comments below, and don’t forget to follow us on &lt;a href="https://twitter.com/oktadev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and &lt;a href="https://www.youtube.com/channel/UC5AMiWqFVFxF1q9Ya1FuZ_Q" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;. Until next time, rock on!&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>entityframework</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
