Summary: We are going to set up a simple web service coded in C# using .Net Core. To accomplish this we’ll learn some C# fundamentals, then use .Net’s scaffolding to create a web api and development server we can run. We will interact with this web api using a simple angular app.
- Node & npm
- https://nodejs.org/en/
- npm install npm@latest -g
- Angular CLI
- npm install -g @angular/cli
- .Net
- VS Code or similar editor
- Other tools I will use today
- Command prompt/powershell
- Postman
- Git (Tortoisegit, Github)
SlideDeck: https://docs.google.com/presentation/d/1b0fSk83hGGmUuswDBqIS5EnewJmCb2C6JNE3-w_Z6o8/edit?usp=sharing
C# (pronounced C sharp) is a general-purpose, multi-paradigm programming language encompassing strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines.
- General purpose language
- Strongly Typed
- Object Oriented
- History, Open Source status
- Anatomy of a POCO
- Anatomy of an 'n-teir web app'
- Anatomy of our project
- Anatomy of a controller
- Getting started
- Make a new folder CSharpService
- Every front end needs services that connect it to the backend/data storage
- Front end will be a simple provided Angular App
- Get this from Github
- Run from command line
- cd todo-app
- npm install
- ng serve
- open http://localhost:4200/
- Get project scaffolding
- In CSharpService create a new folder TodoApi
- Open Terminal to CSharpeService/TodoApi
- run
dotnet new webapi -i TodoApi
- Open this folder in your editor
- Handle debris
- Delete the ValuesController.cs
- update line 24 of launch settings to
"launchUrl": "api/todos",
"applicationUrl": "http://localhost:3000",
- Handle CORS by updating startup.cs
- line 22 add
readonly string MyAllowSpecificOrigins = "_myAllowSpecificOrigins";
- Line 29 add
services.AddCors(options =>
{
options.AddPolicy(MyAllowSpecificOrigins,
builder =>
{
builder.WithOrigins("http://localhost:4200");
});
});
- Line 53 add
app.UseCors(MyAllowSpecificOrigins);
- Create Model
- Create new Models folder in TodoApi
- Add file in Models folder named TodoItem.cs
- Put this code in
namespace TodoApi.Models { public class TodoItem { public long Id { get; set; } public string Title { get; set; } public bool IsComplete { get; set; } } }
- Note that this matches out Todo.ts!
- Create a controller
- New file in the Controllers Folder called TodosController.cs
- Insert code outline
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using TodoApi.Models;
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class TodosController : ControllerBase
{
private static long? TodoCount;
private static Dictionary<long, TodoItem> Todos;
public TodosController()
{
if (!TodoCount.HasValue)
{
TodoCount = 0;
}
if (Todos == null)
{
Todos = new Dictionary<long, TodoItem>();
}
}
}
}
- Note theDatastore This is a simple static dictionary that will only live as long as our service is running, won't support concurrency!
private static long? TodoCount;
private static Dictionary<long, TodoItem> Todos;
- Also note the constructor sets everything up
public TodosController()
{
if (!TodoCount.HasValue)
{
TodoCount = 0;
}
if (Todos == null)
{
Todos = new Dictionary<long, TodoItem>();
}
}
- Implement Post Operation
- Do Code
// POST api/values [HttpPost] public TodoItem Post([FromBody] TodoItem value) { if (Todos == null) { throw new Exception("Todos is null"); } var insertValue = new TodoItem { Id = TodoCount.Value, IsComplete = value.IsComplete, Title = value.Title }; if (!Todos.TryAdd(TodoCount.Value, insertValue)) { throw new Exception("Todo already exists"); } TodoCount++; return insertValue; }
- Spin up service from command line
dotnet run
- Connect with angular app
- Implement a Get All Operation
- Do code
// GET api/values [HttpGet] public ActionResult<IEnumerable<TodoItem>> Get() { if (Todos == null) { return null; } return Todos.Values; }
- Spin up service from command line
dotnet run
- Connect with angular app
- Implement a Get Single Operation
- Do code
// POST api/values [HttpPost] public TodoItem Post([FromBody] TodoItem value) { if (Todos == null) { throw new Exception("Todos is null"); } var insertValue = new TodoItem { Id = TodoCount.Value, IsComplete = value.IsComplete, Name = value.Name }; if (!Todos.TryAdd(TodoCount.Value, insertValue)) { throw new Exception("Todo already exists"); } TodoCount++; return insertValue; }
- Spin up service from command line
dotnet run
- Connect with angular app
- Implement Put/Update Operation
- Do Code
dotnet run// PUT api/values/5 [HttpPut("{id}")] public TodoItem Put(long id, [FromBody] TodoItem value) { if (Todos == null) { throw new Exception("Todos is null"); } if (id != value.Id) { throw new Exception("Id and Todo Id mismatch"); } if (!Todos.ContainsKey(id)) { throw new Exception("Todo doesn't exist"); } Todos.Remove(id); Todos.Add(id, value); return Todos[id]; } ``` 2. Spin up service from command line
3. Connect with angular app
- Implement Delete Operation
- Do Code
// DELETE api/values/5 [HttpDelete("{id}")] public void Delete(long id) { if (Todos == null) { throw new Exception("Todos is null"); } if (!Todos.ContainsKey(id)) { throw new Exception("Todo doesn't exist"); } Todos.Remove(id); }
- Spin up service from command line
dotnet run
- Connect with angular app
- What we learned from this
- Simple process that could be dockerized provides back end for front end application
- https://docs.microsoft.com/en-us/aspnet/core/getting-started/?view=aspnetcore-2.2&tabs=windows
- https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.2&tabs=visual-studio
- https://www.sitepoint.com/angular-2-tutorial/ (THIS IS OLD AVOID IT)
- https://en.wikipedia.org/wiki/C_Sharp_(programming_language)
- .Net Core
- In depth HTTP
- Object Oriented / Inheritance / Interfaces
- Unit Testing
- IL / .Net (what makes C# into machine code)
- Dependency Injection
- Error Handling
- Async/Await, Tasks, concurrency
- IIS & other web servers
- Nuget
- Angular (in any way)
- EntityFramework