Lately I???ve been??building??websites with??AngularJS,??TypeScript,??WebApi??and??Entity Framework 6??(and??Bootstrap, obvs!).??A lot of the work is repetitive grunt-work, generating the model, then the DTO, then the WebApi controller, etc. For a little while now I???ve been using my own ???code generator??? tool to scaffold out these ???templates???, which saves me a lot of??work. Recently I open-sourced the??project on GitHub, and now I???ve got a chance to blog about it.

I???ve also set up a hosted version, which you can play with??now, to see how it works. Simply head over to??http://codegenerator.sitedemo.co.za/??and log in with the following credentials:

  • Username:??demo@capesean.co.za
  • Password:??L3tM3!n

Here follows an explanation of how to use it, and what it does.

Projects

When you first log in, you will see a list of projects. Click the??Demo Project??for now. You will see a page like the following:

You can see there are 4 entities: Product, Customer, Order and Line Item (we all know where this is going, right?)

You???ll see 13 columns in the table:??Model,??Enums,??DTO,??SettingsDTO, etc. These are the outputs that will be generated by the tool. More on these later.

Entities

Clicking on the Customer entity link, takes us to the following webpage:

Some entity-level fields are hidden under that??More >??button, but we???ll ignore those fields for now. More importantly you see the 3 fields on the entity:??CustomerId,??Name, and??Telephone. You can add more fields, rearrange the order, or click on a field row to edit that field.

Beneath the fields are the relationships with other entities: those relationships where the??Customerentity is the parent, and then where it is the??Child.??Customer??is a parent of??Orders, so you can see the relationship to the??Orders??entity listed.

Beneath that you???ll find??Code Replacements. Code Replacements allow you to customize the??generated outputs. More on that in another post, though.

Fields

For now, let???s click??the??Name??field. This brings up the following page:

Here you can see some standard things you???d need for a field: a field name, a label, the data type (e.g. nVarchar), the Length, whether it???s a key field, if it???s unique, if it???s nullable, whether it???s a search field, whether it should be shown on the search results page, a sort order, etc. So enough to get you started.

The Code!

Back on the entity page, if you click the blue??Code </>??button, you???ll get to this page:

Here you???ll find 13 checkboxes and 13 tabs: one for each of the output files that the Code Generator tool produces. (The checkboxes are for deploying the outputs directly to your local??folder, if/when the tool is installed on your development machine ??? again, more on that??in a later post).

The Model Code

For now, you???ll see that the tool is generating a Model file in the screenshot above. It???s??outputting the key field,??CustomerId, which is a Guid. The??Name??field is a 250-length string, with an index for uniqueness. There???s also a navigation property to the??Orders??collection, which is produced because of the relationship defined from Customers to Orders.

The WebApi Controller Code

Let???s look at the WebApi controller code next:

So the API is protected with??Authorize(Roles =?????Administrator???), and the??route prefix is??api/customers.

There is a??Search??end-point which??takes an optional paging object, for paging through results, and then a string search parameter??q.??If this is supplied, the??controller will search in the??Customer.Namefield for any matches, because the??Name??field was defined as a text-search field. The name field was also designated as??a sorting field, so the results are sorted by the??Name. The controller then gets a paginated response object, and??converts the model to the DTO using the??ModelFactory.Createmethod.

Further down you???ll see a??Get??method, for returning a single item. Then an??Insert??and??Update??method, which both use a private??Save??method, and lastly a??Delete??method.

The AngularJS (TypeScript) Code

Ok, let???s look at what it does from the AngularJS / TypeScript side. Here is the output for the AngularJS controller, for the Edit page:

Ok, so this is a standard AngularJS controller, with several items injected. Let???s look at what it does.

There???s an??initPage??function which runs when the controller loads. It determines via the??$stateParamsif the entity is being added (new) or loaded (existing). If it???s being loaded, it uses the??customerResource??(ngResource)??to??.get??the appropriate record. That???s really it, in a nutshell.

Then there???s a??save??function, which saves changes up to the API.

Then there???s a??delete??function, which will delete the entity.

And lastly there???s a??loadOrders??function, which will load the customer???s orders, using the pagination parameters that were mentioned briefly in the??Controller??section above, so??it will display 10 orders at a time with a pager to move through them.

The Html Code

Lastly, let???s look at an Html??page that gets output.

Here???s the Html that??works with the??AngularJS controller. I???m not going to go into detail, but you???ll see it uses Bootstrap 4 (although there???s a setting for 3 on the Project), it does a bit of validation and uses??ng-messages, has the??Save??and??Delete??buttons, and then displays the customer???s orders in a list at the bottom (if the customer record is not new).

Hopefully that explains it enough to show you what it can do. Obviously you???ll need to have a project with the appropriate supporting files (e.g. the BaseApiController.cs, the WebApiConfig.cs, the ApplicationDBContext.cs, etc). However, the CodeGenerator project on GitHub has all these files in it! So you can simply strip out the??files related to the CodeGenerator, and paste in??the files from your project, and you should be good to go. (If you???re struggling with getting that set up, I can/will provide an ???empty??? project that you can start with, if it would help.)

Let me know if you find it useful, and if you??hit any issues. Hopefully this will help someone???s productivity as much as it???s helped mine!

I’ve started working with AngularJS for any new websites, and one of the first things I??needed to revisit was the authentication strategy. Pretty much every website I build requires the user to be logged in to access (at least part of) the website. I wanted to??put together a ‘template’ that I could reuse each time I start a new project. TLDR: the end result is up on github at:??https://github.com/capesean/JWTKickStart After doing some research, I??really like OAuth2 and JSON??Web Tokens (JWT). I use .NET on the server, but??one of the appeals of JWT and Angular was a complete decoupling of the??browser app from the server’s API. As you’ll see from the Github repo, there are two Visual Studio??projects:

  • APP: this is the AngularJS application. Although it’s in a Visual Studio project ‘container’, there is no dependency on Visual Studio at all.
  • API: this is the server back-end, which has been built using .NET’s WebAPI 2 with OWIN & C#. Although, as mentioned, this could??be any API that issues JWT tokens & refresh tokens.

Before I start,??my inspiration came from the following sources:

  • The??BitOfTech blog??by??Taiseer Joudeh??is an amazing resource for Angular/JWT/.NET/OWIN articles. Just amazing. Thank you, Taiseer! However, the main series of articles I drew from used OAuth bearer tokens,??not??JWT tokens. There are other articles that??cover JWT tokens. I rewrote??some aspects??(e.g. the??Refresh Token side) for JWTs.
  • I also really liked??this article??on the Brewhouse.io blog. It shows how to build a modal login that pops up if the user makes an API call which is??not authenticated, giving the user a change to re-enter his/her credentials before re-attempting the API call,??which is very slick. I extended this to use the Refresh Token before requiring the modal login.
  • In the comments on the Brewhouse.io article is a??video from a talk??by Martin Gontovnikas, from Auth0. He suggests a very similar strategy. Some new nuggets in there too, though.

Some of my requirements:

  • Typically my requirements won’t include multiple clients (website, mobile app, etc.), so I removed the multi-client aspect (where client data gets stored in the database) to keep the starting point simple. It should be relatively easy to add back:??check out the BitOfTech articles if that’s a requirement.
  • Typically I??wouldn’t need to cater for CORS either,??so I initially left that part out. However, when I separated the system into the two projects (APP & API), that run??on two localhost ports,??then I needed to add it back. So it’s a pretty simple CORS * at the moment, but for production??it’s easy enough to remove the CORS AppSetting so it falls back to a same-origin policy.
  • Typically I would have the Resource Server, the Authorization Server, and the Authentication Server as one & the same. I don’t need Facebook etc. logins (I only require??username & password access), and my API backend handles everything: authentication, authorization, and the actual API itself. So I merged these all into one.

Some notes for??setting it up to run:

  • A SQL Server .bak file is included in the API projects App_Data folder.
  • When it’s run, it will create a user with??username ‘test@test.com’ and password ‘password’ in the database.
  • The token & refresh token??Url is at /token
  • An authorisation protected resource is at Url /api/protected
  • Login details are prefilled in the login forms
  • Settings for the API project (e.g.??Base64 encoded secret, connection string, Client Id, token expirations, etc.) are stored in web.config.
  • When logged in, you should see your jwt & refresh??tokens outputted as JSON, and the response from the protected API call, which??outputs??the claims for the logged in user, as shown below: JWTKickStart
  • You can set the auth token to expire in a minute (1), and then log in: after a minute, the system will use the refresh token to keep you logged in. The neat thing here is, if your??claims have changed,??I’ve built it to update??the ticket,??so for example if your permissions change,??the app will ‘silently’ get updated with your new status.

I’m going to (hopefully) maintain this repo,??so it’s always a good boilerplate project to get started with. In the meantime, here’s the Url again: https://github.com/capesean/JWTKickStart I hope it helps someone!