ASP.NET Core Basics: Razor Pages

As part of the ASP.NET Core 2.0 release, a new feature called Razor Pages was added to better handle page-focused scenarios. This post is going to cover adding usage of Razor Pages to an existing ASP.NET Core MVC application. This is part of the ASP.NET Core Basics series and the repo before any changes for this post can be found here. All the changes will be in the Contacts project if you are using the sample repo.

Add the end of this post the Razor Pages example will have the same level of functionality as the existing Razor example in the project.

Setup

To follow the conventions of a new Razor Pages project add a  Pages directory to the root of the project. As another level of grouping add a ContactsRazorPages directory under the  Pages directory. The strange name of the directory is just to make it super clear this is different than the existing Contact List already in the application.

Scaffolding

Razor Pages supports the same level of scaffolding as the existing Razor/MVC setup we are all used to in Visual Studio. To start, right-click on the  ContactsRazorPages directory and select Add > Razor Page.

This will open the Add Scaffold dialog. We are using entity framework and want to generate a full set of CRUD operations so select Razor Pages using Entity Framework (CRUD) and click Add.

Next, we have to select the Model and DB Context. We want to use the same model and context as our existing Razor/MVC setup so we are going to select the Contact class and the ContactsContext DB Context. Finally, since this is part of an existing application make sure and check the Use a layout page and use the existing  _Layout.cshtml page used by the rest of the application. Click the Add button and hang out while the magic happens.

After a couple of minutes, the directory will be filled with a set of pages to do contact CRUD operations. Since this is a page-centric method of working all the files you need are in this one directory. No separate controller and views as in traditional MVC. By default, routing is handled via the folder structure.

View Imports

I had to a  _ViewImports.cshtml file to the  Pages to get things working. I tried adding the needed imports to the existing import, but it didn’t work for some reason. Here are the contents of the file.

Add to the Navigation Menu

Our last step is going to be to add the new contact list to the site’s navigation menu. Open the  _Layout.cshtml file in the  Views/Shared directory and a link to the new contact list.

Notice that the link uses the  asp-page tag helper instead of  asp-controller.

Wrapping Up

The above covers adding Razor Pages to an existing MVC application and rounds out the all the major UI options for the ASP.NET Basics series. Keep in mind that Razor Pages functionality is fully on par with tradition MVC and has been recommended by Microsoft as the way to do when page-centric work. If you haven’t check out the getting started docs to get a better feel for how to use pages.

The completed code can be found here.

Identity Server: Upgrade Client to Angular 5

I have been working a lot on my basics sample project to explore some new client-side frameworks (React and Vue if you are interested). Since I have been away from the Identity Server sample for a while I thought it would be good to see what updates the project might need. It turns out that Angular was the big thing that was out of date. This post is going to cover the changes to get the project updated to Angular 5.

Package.json

In the Client App project open the  package.json file and update the version of the  @angular packages to at least the following version, and of course feel free to pin the exact version. I don’t just because of the nature of this sample.

At this point, I tried to run and got an error about the version of  rxjs being used. Instead of just blindly going package by package and seeing which versions were required I installed the Angular CLI and created a new Angular 5 application and used it as an example of what version I needed. Use the following commands if you would like to follow the same process since the current versions have changed by the time you are reading this post.

The above led me to the following version changes.

Attempt 2

At this point, I tried running the application again and received the following error.

Error: Version of @angular/compiler-cli needs to be 2.3.1 or greater. Current version is “5.0.1”.

As you can imagine I was surprised that 5.0.1 < 2.3.1. Turns out this is related to the version of @ngtools/webpack. This package deals with ahead-of-time compiling which my sample application uses, but the application I generated using the Angular CLI doesn’t. Updating to the following version cleared up the issue.

Open ID Connect Client

There was a much new version of the Open ID Connect Client that the Angular application is using so I upgrade it as well to the following version.

This version dropped the  startup_route so the following line had to be removed from the  AuthService class.

Final Steps

Now that the package versions are sorted run the following commands from a command prompt to make sure that all the new version are installed and in the proper places.

Wrapping Up

I am glad to have this upgrade done. It seems that every time I do one of these upgrades I end up down some rabbit hole. On the plus side, I seem to be getting faster at resolving the rabbit hole issues, or the frameworks have made a lot of progress on making sure the upgrade processes are simpler than they used to be. Either way, I get to expand my knowledge. I just need to schedule a bit more time before attempting upgrades.

The code in its finished state can be found here.

Vue: Contact Detail

Last week’s post covered adding a Vue project to the ASP.NET Core Basics example solution. This post is going to cover adding a read-only view of a contact’s detail to being the Vue sample a step closer to being in line with the Angular, Aurelia and React samples. The code before any changes can be found here.

Contact Class

The  Contact interface in the  contactlist.ts file should be deleted. Add a  contact.ts file to the  ClientApp/components/contacts/ directory. This will hold the replacement for the interface we just deleted. The full class definition follows.

This class is very simple and will be used later to show how a function call can be used as part of a view.

Contact Service

Since the application will now have two places that need to access the ASP.NET Core API lets to refactor the API access into a service. This is the same style used by the Aurelia, Angular and React applications. Add a  contactService.ts file to the  contacts directory. The service will provide functions to get all contacts or a single contact an ID. The following is the full class.

Now the API access in the  ContactListComponent can be refactored to use the service. First, add imports for contact and service.

Next, replace the fetch call with a service call.

Contact Detail Component

Add a  contactDetail.ts which will be the backing component for the contact detail view. The following is the full class. Pretty much all it is doing is using get contact service to get contact detail by ID when it is mounted.

Now add a  contactDetail.vue.html file for the UI bits of the contact detail. This is basically just HTML with the same binding syntax as before. Notice that the binding of address is a function call. The other Vue things to note are that the details will only show if contact is truthy using the v-if.

Routing with a Parameter

Finding the proper way to route with at parameter in Vue was not easy. The way it is done has evolved over time making find the right way a little challenging. The first step is to add a route for the contact detail by adding a new item to the  routes array in the  boot.ts file.

The  :id in the path denotes a parameter. The  props: true bit is also key to getting the ID when in the contact detail component. The  contactlist.vue.html needs to be updated to link to the contact detail route.

Finally, in the  ContactDetailComponent we need to use the ID. To do so we need an import to allow the use of the Prop decorator.

Now all that is needed is to apply the decorator to a property of the class that matches the name of the parameter in the route.

Now the ID can be used to get the proper contact from the contact service. The following is code that was already shown, but the full context of how the prop decorator is used is important so I am repeating it here.

Wrapping Up

This brings the projects one step closer to being on the same level feature-wise. Look for one more post to get the Vue project features lined up with the other samples in the solution.

Keep in mind that this is my first look at Vue and my examples may or may not be idiomatic.

The code in a finished state can be found here.

ASP.NET Core Basics: Vue with an API

In the past, I have done some exploration on AureliaAngular and React via the ASP.NET Core Basics series. This post is going to take a similar approach using Vue. The code for the project will be in the same repo as the previous basics examples and will be utilizing the same API to pull data. The code before adding the Vue project can be found here.

Project Creation

There is not a template for Vue built into Visual Studio, but there is a set of templates that can be used via the .NET CLI with the  dotnet new that includes Vue (as well as Aurelia and Knockout). A full list of available templates can be found here. The template we need is Microsoft.AspNetCore.SpaTemplates and can be installed using the following command from a command prompt.

Create a Vue folder at the same level as the other projects, for the samples this would be in the  src folder. In the command prompt navigate to the  src/Vue/ directory. Run the following command to create the Vue project.

After the project generation completes run the following to get the needed npm packages installed.

The last step is to get the new project added to the existing solution. Navigate the command prompt to your solution file. For the sample project, this is the root of the repo. Then run the following command (this could also be done through Visual Studio instead of using the CLI).

Adding the Contact List

In the  ClientApp/components directory add a new  contacts directory to house all the awesome contact related functionality we will be adding. Next, add a new  contactlist.ts. To this new file add the interface which defines what a Contact looks like.

Above the contact interface, add the following imports needed to create a Vue component.

Finally, add the contact list component. This component maintains a list of contacts which gets filled from our existing API when the component is mounted (see the docs for more information on Vue’s lifecycle hooks).

The following if the full component just to provide full context.

Next up is the UI for this contact list component. In the same directory add  contactlist.vue.html.  The following is the full file.

All of the above is pretty straightforward. All the Vue specific items have a  v- prefix.

Add the Contact List to Navigation

The last bit needed to have a working contact list is adding it to navigation so the user can get to the list. The routes are defined in the  boot.ts file in the  routes array. Add the following line to the array to handle our contact list.

Now that the router knows to handle the contact list it needs to be added to the navigation UI. Open the  /navmenu/navmenu.vue.html file and find the unordered list that is the navigation menu. Add a new list item to provide a link to the contact list.

Wrapping Up

Vue reminds me a lot of Aurelia in its simplicity so far which is awesome. Look for the same progression of posts for Vue that happened with React over the last few weeks.

The code in its final state can be found here.

React: Form for Contact Add

Last week’s post covered adding a read-only view of a contact’s details. As before the goal is to get the React project’s features in line with the Aurelia and Angular samples. This week we will be adding a form to all addition of a new contact. The code before any changes can be found here.

Contact List

On the contact list page, we need to add a link to create a contact. This will be added just after the header in the  ContactList.tsx file.

Routing

In order to stay in line with the other sample, the  ContactDetail component is going to be handling both the read-only view and the view to add a contact. This means the ID that is currently part of the contact detail needs to be optional. The following is the change to make ID optional by adding a question mark.

Contact Service

In the  ContactService class, we need to add a  save function. This new function will make a post request to the contacts API and return the new contact with the ID from the API to the caller.

Contact Detail

The  ContactDetail class is where most of the changes are. I had some trouble getting React’s forms to work directly with the instance of the contact class and ended up just storing the parts of a contact directly in state instead of as an object. I expect this is a failure on my part and not an issue with React. I may revisit this in the future. Below is the new structure of the state used by contact details.

Next, the  constructor needed to be changed to handle the new state structure and to handle being called without an ID.

Again, this is way more code than it would be the contact class were being used. Next, the render function needs to be adjusted to render the UI for the read-only view or the contact creation. The decision is based on the ID being set or undefined.

The render of an existing contact needs to be changed to use state instead of an instance of a contact.

The following is the render of the add contact UI. I will call out a couple of parts after. The bulk of the code is just rending of the form.

The following is the input for the contact’s name.

Since I decided to go with the controlled component route React will be responsible for being the source of truth, not the form its self. To accomplish this it is important that the input has a  name and an  onChange event handler set up. The following is the  handleChange function which uses the name from the on change event to update the proper property in the component’s state.

The following line is the reset button which will reset the state to blank out all the fields in the form.

<button className="btn btn-danger btn-lg" onClick={() => this.reset()}>Reset</button>

The  reset function just uses  setState to blank out all the fields.

Not surprisingly the submit button triggers a submit of the form. What happens on submit is defined in the opening form tag.

The  handleSubmit function takes the contact information in state and uses it to create a new instance of a  Contact which is then passed to the  ContactService to be saved. The service returns a new contact object from the server and the ID is stored to state.

If the server does return an ID for the new contact then the  redirect is set to true. Then will case the following code to run in  renderNewContact which will redirect the user back to the read-only view of the new contact.

Wrapping Up

This pretty much gets the React application in line with the Aurelia and Angular sample applications. It has been fun getting a handle on the very, very basics of React. While I am back in the basics sample projects I may go ahead and tackle a Vue sample next.

The finished code can be found here.

React: Contact Detail

Last week’s post covered adding a React project to the ASP.NET Core Basics solution. As I stated last week the goal is to get the React project’s features in line with the Aurelia and Angular samples. This week we will be adding a read-only view of a contact’s details. The code before any changes can be found here.

Contact Class

The  Contact interface in the  ContactList.tsx should be deleted and in its please we will add a  Contact class. As part of this change, I also moved the contact related items to a contact directory. Add a  contact.ts file to the  ClientApp/components/contacts/ directory with the following contents.

This class is very simple and will be used later to show how a function call can be used as part of rendering.

Contact Service

Since the application will now have two places that need to access the ASP.NET Core API I decided to refactor the API access behind a service. This is the same style used by the Aurelia and Angular applications. Add a  contactService.ts file to the  Contacts directory. The service will provide functions to get all contacts or a single contact using its ID. The following is the full class.

The final step in this refactor is to use the new service in the  ContactList class. First, add imports for the service and  Contact class.

Then, replace the fetch call with the service.

Contact Detail Component

Add a  ContactDetail.tsx file which will be used to show the details of a contact including using the  getAddress function of the  Contact class. The following is the full contents of the file.

This is all very similar to the things I have covered before. Now that we have a contact detail component we need a way to display it.

Routing with a Parameter

Import the contact detail in the  route.tsx file.

Next, add a route path for contact detail that expects an ID.

Back in the  ContactList component change the ID to be a link to the new contact detail route using the ID of the contact.

The code for pulling the route parameter was in the  ContactDetail component above, but I am going to show it again just so all the route with parameter information is together. The route parameters can be accessed using  props.match.params.{parameter name} which in this case ends up being  props.match.params.id. The following is the constructor of the  ContactDetail component which is using a route parameter.

Wrapping Up

This brings the projects one step closer to being on the same level feature-wise. I expect at least one more post to get the project features lined up so make sure and keep a lookout for the next post.

Keep in mind that this is my first look at React and my examples may or may not be idiomatic. So far I am really enjoying working with React.

The code in a finished state can be found here.

ASP.NET Core Basics: React with an API

In the past, I have done some exploration on Aurelia and Angular via the ASP.NET Core Basics series. This post is going to take a similar approach as I start doing some exploration with React. The code for the project will be in the same repo as the previous basics examples and will be utilizing the same API to pull data. The code before adding the React project can be found here.

This post is going to cover adding a React project to the existing using the React template that is now built into Visual Studio. The same thing can be accomplished using the .NET CLI so don’t feel like Visual Studio is required. The goal for the React project in this initial post will be to connect to the contacts API and download a list of contacts and render that to the screen. In future posts, I hope to expand this functionality to match that of the Aurelia and Angular projects.

Project Creation

Right-click and select Add > New Project.

In the Add New Project dialog select the ASP.NET Core Web Application. In the case of the sample, the project will be named React. Click OK to continue.

On the next screen make sure and select ASP.NET Core 2.0 and the React.js template. Then click OK.

The following is the resulting React project in the context of the full solution.

Next, make sure and run npm install from a command prompt in the React project’s directory to ensure all the npm packages get restored.

Adding the Contact List

Inside the  ClientApp/components/ directory add a file name  ContactList.tsx. TSX is the TypeScript version of the React JSX file type. The official docs on JSX can be found here. Since this is my first time working with React I took the  FetchData.tsx file and copied the contents and used that as the starting point for my contact list. To lead with there is an interface for what should define a contact.

Next, we have an interface for the state of this component with contains a loading flag and an array of contacts.

In the constructor for the component is where the data is pulled from the API using  fetch. The data from the API is then saved to the state of the component using the  setState function.

Next, the component has a function named  renderContactsTable which takes an array of contacts and returns how they should be rendered. In this case, the contacts are rendered to a table that displays the contact ID and Name.

Finally, there is the render function. As you can guess this is what gets called to render the component. In this case, either “Loading” or the contact list gets displayed depending on if the contact list data has been loaded or not.

The following is the full file for reference.

Add Contact List to Navigation

Now that we have the contact list component it needs to be added to the navigation menu. The first step is to add it to the application’s router. This can be found in the  routes.tsx file. The file is short so I am going to include the full content. Lines 7 and 13 are the ones added to handle our contact list.

The last change is to add a navigation link to the  NavMenu found in the  NavMenu.tsx file. As I am sure most of us are used to adding an item to the nav menu is just adding a new li, but with the React specific  NavLink bit.

Wrapping Up

React is different than both Aurelia and Angular. Don’t take that as a good or bad thing. I don’t plan to pick on a side on the Angular vs React debate I just want to get a good feel for the different frameworks. So far the React experience has been pretty nice and I look forward to doing more exploration.

You can find the finished code for this post here.

Swagger and Swashbuckle with ASP.NET Core 2

This post is going to be very similar to a post from last December which can be found here. A lot has changed since then and this post is going to add Swagger to an existing ASP.NET Core application using Swashbuckle much like the one from last year. The starting point of the code can be found here.

What is Swagger?

Swagger is a specification used to document an API. As I am sure we all know API documentation tends to get out of date fast and a lot of times is a low priority.  Swagger aims to help solve that problem using a format that is both human and machine readable which can be maintained in either JSON or YAML. The documentation can be auto generated using a tool like Swashbuckle which provides away to keep your consumers up to date. Check out this post by the Swagger team for the full introduction.

What is Swashbuckle?

Swashbuckle provides auto generation of Swagger 2.0, a UI, etc. The project takes all the pain out of getting going with Swagger as well as providing tools and hooks for using and customizing Swagger related items. The full description can be found here.

Adding Swashbuckle

Using your favorite method of NuGet interaction, add the  Swashbuckle.AspNetCore NuGet package to your project. Personally, I have gotten where I edit the csproj file to add new packages. If that is your style you would need to add the following package reference.

This one package provides all the functionality we will need.

Wiring up Swashbuckle

Now that the Swashbuckle package is installed, there are a few changes that are needed in the  Startup class to get everything wired up. First, in the  ConfigureServices function, the Swagger generator needs to be added to DI.

AddSwaggerGen allows for configuration of options, but here we are just setting a name and a minimal amount of information.

In the  Configure function Swagger needs to be added to the request pipeline in order to expose the Swagger generated data. I placed this after  UseMvc.

At this point, the Swagger generated JSON would be available at  {yourBaseUrl}/swagger/v1/swagger.json. To take a step further let’s expose the UI that comes with Swashbuckle. Add the following just below  app.UseSwagger().

Now a UI based on your API is available at  {yourBaseUrl}/swagger with zero extra work on your part. The following is the UI for the post contact route in the example project.

As you can see the UI provides a great view of your API as well as ways to try it out and the potential responses that should be expected from a call.

Controller Considerations

All of this wonderful functionality doesn’t come for free of course. In order for Swashbuckle to pick up your routes, your controller will need to use attribute based routing instead of depending on convention based routing.

In order for Swashbuckle to know the return types and of your controller actions may need to have some attributes added. This won’t be required if your action return a specific type, but if you are returning an  IActionResult you should attribute your action with all the  ProducesResponseType you need to cover the results of your action. For example, the following is the action definition for the Post in the screen shot above.

Wrapping up

Swashbuckle makes it easy to add Swagger to a project. I feel that it also provides a huge value for anyone trying to consume an API. It is of course not a magic bullet and communication with your API consumers about API changes will still be critical.

Microsoft’s docs have a great walk through which can be found here. It does more in-depth on customizing your setup and as far as modifying the look of the UI. I also recommend checking out the GitHub page for the project which can be found here.

The finished code can be found here.

Migration from ASP.NET Core 1.1.x to 2.0

On August 14th .NET Core 2.0 was released including corresponding versions of ASP.NET Core 2.0 and Entity Framework Core 2.0 which got with the finalization of .NET Standard 2.0. The links take you to the release notes for each item.

In this post, I will be covering taking the project used for the ASP.NET Basics series from 1.1.x to the 2.0 release. The starting point of the code can be found here. This post is only going to cover conversion of the Contacts project.

Installation

If you are a Visual Studio user make sure you have the latest version of Visual Studio 2017, which can be found here and at a minimum should be version 15.3.

Next, install the SDK for your operating system. The list of installs can be found here. For development, it is key that you install the SDK, not just the runtime. The following is a preview of what to expect on the download page.

Csproj

The  csproj file of the project being upgraded is the best place to start the conversion. The TargetFramework needs to be changed to 2.0.

Next,  PackageTargetFallback changed to  AssetTargetFallback.

There is a new Microsoft.AspNetCore.All package that bundles up what used to be a huge list of individual packages. Those individual packages still exist, but this new one wraps them and makes it much easier to get started. The following is the package list before and after.

Last change in this file is to change the  DotNetCliToolReference versions to 2.0.0.

Program.cs

Program.cs is another area that has been simplified by creating a default builder that does all the same things that were happening before but hide the details. Keep in mind the old version still works and is valid to use if you use case needs it.

Identity

The remaining changes I had to make were all related to Identity. In the  Startup class’s  Configure function the following change was needed.

Next, in the  ManageLoginsViewModel class, the type of the  OtherLogins property changed.

The  SignInManager dropped the  GetExternalAuthenticationSchemes function in favor of  GetExternalAuthenticationSchemesAsync. This caused changes in a couple of files. First, in the  ManageController the following change was made.

The second set of changes were in the  Login.cshtml file. First the function change.

Then the change to deal with the changed property names.

Wrapping up

With the changes in the Contacts project now works on ASP.NET Core 2.0!  Make sure to check out Microsoft’s regular migration guide. as well as their identity migration guide. A full list of breaking changes for this release can be found here.

There is a lot more to explore with this new release and I have a lot of projects to update. Don’t worry I won’t be doing a blog post on all of them, but if I do hit any issues I will create a new post of update this one with the fixes. The finished code can be found here.

Upgrading a JavaScript Services Application

As part of the ASP.NET Core Basics series of posts, JavaScript Services was used to create a couple of front end for a basic contacts API using Aurelia and Angular 2. Theses applications were created a few months ago and JavaScript Services has kept moving since then. This post is going to look at one strategy for taking an application created on an older version of JavaScript Services and update it to match the current version. This post will be following the upgrade of the Angular project from ASP.NET Core Basics repo with the starting point of the code being from this release.

The strategy

One of the considerations when doing this upgrade was getting the changes that happen on the ASP.NET Core side of the application and not just the JavaScript bits. In order to make sure that nothing was missed I decided to use JavaScript Services to generate a new application and use that to compare with the implementations in the existing application.

Create comparison application

This is going to assume JavaScript Services is already installed. If it isn’t this page has instructions or this post has sections that deal with creating a new application using JavaScript Services.

The update

Following is the files that changed during this update. This is also the list of files I would check anytime an upgrade needs to be done.

There were a fair amount of changes in the files listed above and instead of posting the code the differences can be found here. The previous diff didn’t contain the webpack.config files and those diffs can be found here and here.

After all the files have been updated make sure to run the following command from a command prompt in your project directory to make sure webpack has vendor related items regenerated.

Wrapping up

This post is a lighter on the details that I do most of the time, but this type of upgrade would just have been a wall of code and not been overly useful and the commits on GitHub are a much better guide to what the upgrade looked like. My feeling is that over time the number of changes going forward may end up being smaller and easier to integrate.

Both the Aurelia and Angular projects have been upgraded and the final version of the code can be found here.