SlideShare a Scribd company logo
No Content Here
(Reserved for Watermark)
Introducing
ASP.NET Core 2.0
@ardalis
Ardalis.com
Steve Smith
(in about an hour)
No Content Here
(Reserved for Watermark)
No Content Here
(Reserved for Watermark)
Weekly Dev Tips
Podcast and Newsletter
• Ardalis.com/tips
• WeeklyDevTips.com
No Content Here
(Reserved for Watermark)
Being updated for 2.0 – should be done this month
https://www.microsoft.com/net/learn/architecture
See also AspNetCoreQuickstart.com online course
Contact me for team training and/or mentoring
Free eBook and Sample
No Content Here
(Reserved for Watermark)
Agenda – My ASP.NET Core Top 10 List
1. Why ASP.NET Core?
2. Using the CLI
3. Startup
4. Managing Dependencies
5. Managing Middleware
6. ASP.NET Core MVC and Web APIs
7. Tag Helpers
8. Razor Pages
9. Testing ASP.NET Core
10. What’s New in 2.0
Full online course w/demos at:
AspNetCoreQuickstart.com
No Content Here
(Reserved for Watermark)
ASP.NET Core – What is it?
A new open-source and cross-platform framework
for building modern cloud-based Web applications
using .NET
No Content Here
(Reserved for Watermark)
Modular – NuGet Package-based
Cloud and Container Optimized – Smaller memory
footprint
Open-Source with Contributions – even the docs
Fast! - 8x Faster than Node; 3x Faster than Go
Cross-Platform – Windows, Mac, Linux
Choice of Tools and Editors – Any Text Editor plus CLI,
or Visual Studio
Goals
No Content Here
(Reserved for Watermark)
Install SDK
https://www.microsoft.com/net/download/core
Optional: Install Visual Studio 2017
Install VS2017 .NET Core 2.0 Tools
Confirm Version:
Getting the Bits
No Content Here
(Reserved for Watermark)
Visual Studio .NET Core Templates
Console App
Class Library
Unit Test
xUnit Test
ASP.NET Core
No Content Here
(Reserved for Watermark)
ASP.NET Core Project Templates
Empty
Web API
Web App
Web App (MVC)
Angular
React
React and Redux
Docker
No Content Here
(Reserved for Watermark)
New Web Projects with dotnet
dotnet new web
Empty Hello World Project
dotnet new mvc
MVC Template
--auth Individual adds identity support
--use-local-db true uses localdb instead of SQLite
dotnet new webapi
dotnet new razorpages
dotnet new angular | react | reactredux
Use --help to view options in CLI
No Content Here
(Reserved for Watermark)
dotnet CLI Templates
No Content Here
(Reserved for Watermark)
dotnet new razor
No Content Here
(Reserved for Watermark)
Razor Pages
Convention-Based Routes
No Controllers; No Actions
PageModel as Codebehind
Handlers replace Actions
PageModel as ViewModel
Leverages existing MVC features
Model Binding / Validation
Routing
Filters
Maintains Testability and Separation of Concerns
More in my Razor Pages
article in September 2017
MSDN Magazine
No Content Here
(Reserved for Watermark)
Section
Program.cs
ASP.NET Core
Startup
No Content Here
(Reserved for Watermark)
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.Run();
WebHostBuilder (1.x)
No Content Here
(Reserved for Watermark)
public class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build();
}
WebHostBuilder (2.x)
No Content Here
(Reserved for Watermark)
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
class Program
{
static void Main(string[] args)
{
new WebHostBuilder()
.UseKestrel()
.Configure(a => a.Run(c => c.Response.WriteAsync("Hi!")))
.Build()
.Run();
}
}
A Minimal ASP.NET Core App
No Content Here
(Reserved for Watermark)
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore;
public class Program
{
public static void Main()
{
WebHost.CreateDefaultBuilder()
.Configure(app =>
app.Run(async (context) =>
{
await context.Response.WriteAsync("Hello World!");
}))
.Build()
.Run();
}
}
A Minimal ASP.NET Core App (2.0)
No Content Here
(Reserved for Watermark)
No Content Here
(Reserved for Watermark)
Section
Startup.cs
ASP.NET Core
Startup
No Content Here
(Reserved for Watermark)
Startup
Constructor (optional)
ConfigureServices
Configure
No Content Here
(Reserved for Watermark)
Constructor (optional)
Inject Dependencies (needed by Startup)
Set up configuration (done by default in 2.0)
Set up Startup logging (done by default in 2.0)
No Content Here
(Reserved for Watermark)
public Startup(IHostingEnvironment env)
{
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
if (env.IsDevelopment())
{
builder.AddUserSecrets<Startup>();
}
builder.AddEnvironmentVariables();
Configuration = builder.Build();
}
Startup Constructor (1.x)
No Content Here
(Reserved for Watermark)
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
Startup Constructor (2.0)
No Content Here
(Reserved for Watermark)
Startup ConfigureServices
Add framework services needed by app to services collection
Add application services to services collection
Optional
Configure Options used by app components
Configure third-party container
StructureMap, Unity, Autofac, Ninject, Castle Windsor, etc.
No Content Here
(Reserved for Watermark)
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>()
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
services.AddMvc();
services.AddSingleton<IEmailSender, EmailSender>();
}
Startup ConfigureServices (2.0)
No Content Here
(Reserved for Watermark)
public IServiceProvider ConfigureServices(IServiceCollection services)
{
services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase(Guid.NewGuid().ToString()));
services.AddMvc();
var container = new Container();
container.Configure(config =>
{
config.Scan(_ =>
{
_.AssemblyContainingType(typeof(Startup)); // Web
_.WithDefaultConventions();
});
config.For(typeof(IRepository<>)).Add(typeof(EfRepository<>));
config.Populate(services);
});
return container.GetInstance<IServiceProvider>();
}
Custom DI Container (Structuremap)
No Content Here
(Reserved for Watermark)
Startup.Configure
Configure the application request pipeline
Configure and arrange middleware
Optional
Configure logging for the application
(done here by convention in 1.x; not required here in 2.x)
No Content Here
(Reserved for Watermark)
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseBrowserLink();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Error");
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
}
Startup Configure (2.0)
No Content Here
(Reserved for Watermark)
Section
Built-in and Custom Middleware
Middleware
No Content Here
(Reserved for Watermark)
“Middleware are software components that are assembled into an application
pipeline to handle requests and responses”
Each component in the pipeline is a request delegate.
Each delegate can invoke the next component in the chain, or short-circuit,
returning back up the call chain
What is Middleware?
No Content Here
(Reserved for Watermark)
No Content Here
(Reserved for Watermark)
public void Configure(IApplicationBuilder app)
{
// app.Run terminates the pipeline without calling any later middleware
app.Run(async context =>
{
await context.Response.WriteAsync("Hello, World!");
});
}
Creating Middleware in Startup: Run
No Content Here
(Reserved for Watermark)
public void Configure(IApplicationBuilder app)
{
// app.Use can execute code before and after other middleware
app.Use(async (context, next) =>
{
// do some work
// call the next middleware
await next.Invoke();
// do some additional work
});
}
Creating Middleware in Startup: Use
No Content Here
(Reserved for Watermark)
public void Configure(IApplicationBuilder app)
{
// app.Map can map a path to a function
app.Map(“hello”, HandleHello);
app.Run(async context =>
{
await context.Response.WriteAsync(“Invalid path!");
});
}
public void HandleHello(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync(“Hello!");
});
}
Creating Middleware in Startup: Map
No Content Here
(Reserved for Watermark)
public class MyMiddleware
{
private readonly RequestDelegate _next;
public MyMiddleware(RequestDelegate next)
{
_next = next;
}
public Task Invoke(HttpContext httpContext)
{
return _next(httpContext);
}
}
// Extension method used to add the middleware to the HTTP request pipeline.
public static class MyMiddlewareExtensions
{
public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<MyMiddleware>();
}
}
Moving Middleware to its own classes
No Content Here
(Reserved for Watermark)
Built-in Middleware : Diagnostics
UseDeveloperExceptionPage
UseDatabaseErrorPage – helps configure database
UseBrowserLink
UseExceptionHandler
UseStatusCodePages
UseWelcomePage
UseElmPage / UseElmCapture (preview)
No Content Here
(Reserved for Watermark)
Built-in Middleware
UseIdentity (UseAuthentication in 2.0)
UseStaticFiles
UseDefaultFiles
UseDirectoryBrowser (requires services)
UseFileServer (replaces/combines previous three)
UseRouter
UseMvc (replaces/wraps UseRouter; requires services)
UseRewriter (1.1)
UseResponseCompression (1.1)
UseResponseCaching (1.1, requires services)
No Content Here
(Reserved for Watermark)
Project Dependencies (1.x)
No Content Here
(Reserved for Watermark)
New Project Dependencies (2.0)
No Content Here
(Reserved for Watermark)
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
<UserSecretsId>aspnet-NewIn2-718CDB27-A711-46D2-8222-38EB73FC1D4B</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0"
PrivateAssets="All" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0"
PrivateAssets="All" />
</ItemGroup>
<ItemGroup>
<DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" />
<DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0"
/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..NewIn2.CoreNewIn2.Core.csproj" />
</ItemGroup>
</Project>
Typical Project File (2.x)
No Content Here
(Reserved for Watermark)
Section
Keeping Code Modular and Loosely Coupled
Injecting Dependencies
in ASP.NET Core
No Content Here
(Reserved for Watermark)
Dependency Injection (DI)
Classes request dependencies instead of referencing directly
Dependent object instances are injected as parameters (or properties)
Allows for flexibility and modularity
Classes follow Explicit Dependencies Principle, Dependency Inversion Principle
No Content Here
(Reserved for Watermark)
Explicit Dependencies Principle
Classes should express their requirements through their constructor
Direct use of specific collaborators creates hidden dependencies
Classes with hidden dependencies aren’t “honest” about what they require
Constructor should be a contract that specifies what the class requires
Learn more: http://deviq.com/explicit-dependencies-principle/
No Content Here
(Reserved for Watermark)
Section
ASP.NET Core MVC
(and Web APIs – they are ONE THING now!)
No Content Here
(Reserved for Watermark)
Controllers and Actions
Controllers are collections of actions
Useful for grouping actions into cohesive sets
Used by default for routing and URL generation (e.g. /{controllername}/{actioname})
Actions are methods that handle individual requests
Each request is routed to an action method
No Content Here
(Reserved for Watermark)
An MVC Action
No Content Here
(Reserved for Watermark)
public async Task OnGetAsync(string returnUrl = null)
{
if (!string.IsNullOrEmpty(ErrorMessage))
{
ModelState.AddModelError(string.Empty, ErrorMessage);
}
ExternalLogins = (await
_signInManager.GetExternalAuthenticationSchemesAsync())
.ToList();
ReturnUrl = returnUrl;
}
Razor Pages Entry Point
No Content Here
(Reserved for Watermark)
Routing to Actions
Default route specified in Startup Configure method
Attribute routing (at Controller and/or Action level)
[Route(“products/index”)]
[Route(“products/update/{id})]
[Route(“home”)] on Controller and [Route(“about”)] on Action are combined into “home/about”
route
No Content Here
(Reserved for Watermark)
Attribute Routing Tips
Use default convention where possible
Define routes using attributes for non-default cases, especially for APIs
APIs should use HTTP verb attributes to define routes:
[HttpGet]
[HttpGet(“{id}”)] // will combine with route specified on controller
Routes can use token replacement for [area], [controller], [action]:
[Route(“[controller]/[action]”)]
Especially powerful when used with inheritance:
[Route(“api/[controller]/[action]”)]
public abstract class BaseApiController : Controller
No Content Here
(Reserved for Watermark)
Accepting Data in Actions (Model Binding)
MVC uses model binding to convert data sent by requests into
action parameters
Model binding takes place before the action is invoked
Parameters may be simple types, or complex objects
Data can come from named form values, route components,
or query strings
No Content Here
(Reserved for Watermark)
Model Validation
Model types can have validation rules specified
Actions should check model validation state before making changes to application state
if(ModelState.IsValid)
Avoid using data model types for model binding
This can result in exposing more data to user changes than intended
Use [FromBody] to bind to data in the body of the request (JSON by default)
Use [BindProperty] to bind properties to non-GET requests (2.0)
No Content Here
(Reserved for Watermark)
Tag Helpers
Replaces HTML Helpers (still available, but not recommended)
Render within HTML tags
Declarative, not Imperative
No Content Here
(Reserved for Watermark)
Tag Helper Example
No Content Here
(Reserved for Watermark)
Tag Helper Example
No Content Here
(Reserved for Watermark)
Working With a Database Using EF Core
Add Entity Framework Core (EF Core) in ConfigureServices:
Also supports InMemory – Install this package:
and modify ConfigureServices:
services.AddDbContext<AppDbContext>(options =>
options.UseInMemoryDatabase(“DbName”));
//options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
No Content Here
(Reserved for Watermark)
Working with EF Core’s AppDbContext
Never directly instantiate your application’s DbContext type(s)
Instead, request from DI using constructor parameters
Recommendation
Follow the Dependency Inversion Principle and avoid having UI types depend on
details
Using Entity Framework Core is an implementation detail
Instead depend on an abstraction over your persistence method
Common pattern for this: Repository
No Content Here
(Reserved for Watermark)
Section
Testing ASP.NET
Core Apps
One of my favorite new features!
No Content Here
(Reserved for Watermark)
Configuring a TestServer
Use a WebHostBuilder
Configure like in your web project
Modify for testing if necessary
Create a TestServer from this builder instance
Create an HttpClient using CreateClient()
Make requests to the app using the client instance
No Content Here
(Reserved for Watermark)
Functional Testing ASP.NET Core Apps
Make a request using the HttpClient instance
Capture the response
Verify status code
Deserialize if necessary
Assert that the result included the values you expected
APIs are easy; views require a little more work to configure for testing
No Content Here
(Reserved for Watermark)
[Fact]
public async Task ReturnTwoItems()
{
var response = await _client.GetAsync("/api/todoitems");
response.EnsureSuccessStatusCode();
var stringResponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<IEnumerable<ToDoItem>>
(stringResponse).ToList();
Assert.Equal(2, result.Count());
Assert.Equal(1, result.Count(a => a.Title == "Test Item 1"));
Assert.Equal(1, result.Count(a => a.Title == "Test Item 2"));
}
A Functional Test
No Content Here
(Reserved for Watermark)
protected HttpClient GetClient()
{
var builder = new WebHostBuilder()
.UseContentRoot(Directory.GetCurrentDirectory())
.UseStartup<Startup>()
.UseEnvironment("Testing"); // ensure ConfigureTesting is called in Startup
var server = new TestServer(builder);
var client = server.CreateClient();
// client always expects json results
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/json"));
return client;
}
Configurating the Client
No Content Here
(Reserved for Watermark)
Runtime Store – Precompiles meta-package and eliminates need to deploy its packages
.NET Standard 2.0 – Much larger BCL available cross-platform
DI-Enabled Authentication
Kestrel improvements – now supports edge (Internet-facing) deployment
Hosting environment can inject dependencies and code into apps
Automatic CSRF protection
Automatic Razor view compilation
New Tag Helper Components
IHostedService – start/stop services when application starts/stops
VB support (console, class libraries)
EF Core Owned Entities, Global filters, DbContext Pooling
More New Stuff in 2.0
No Content Here
(Reserved for Watermark)
Demonstration
Razor Pages
and
EF Core New Features
No Content Here
(Reserved for Watermark)
Migration from 1.x to 2.0 Tips
1. Update TargetFramework to netcoreapp2.0
2. Update global.json to version 2.0.0 (if used)
3. Update package references. Use new MS.AspNetCore.All 2.0.0 package. Includes EF Core
2.0.
4. Update other packages to 2.0.0 if needed.
5. Update .NET Core CLI Tools
6. Change PackageTargetFallback to AssetTargetFallback
7. Update Main in Program.cs
8. Make sure you're not doing DB setup in Startup.Configure. Move it to Main in Program.cs.
9. Remove MvcRazorCompileOnPublish = true from .csproj files -- it is now on by default. If
targeting .NET Framework, need to reference ViewCompilation package.
10. If you're not explicitly using App Insights, remove from .csproj, program.cs, and your
_Layout file.
11. Migrate Auth/Identity to 2.0
No Content Here
(Reserved for Watermark)
ASP.NET Core is the future of Microsoft’s
platform
Lots of cool demos I didn’t have time to
show.
Check out AspNetCoreQuickstart.com
Use qltechcon2017 for 20% off
Subscribe to WeeklyDevTips.com
Connect with me on Twitter: @ardalis
Thanks!
Summary

More Related Content

What's hot

Angular - Chapter 4 - Data and Event Handling
 Angular - Chapter 4 - Data and Event Handling Angular - Chapter 4 - Data and Event Handling
Angular - Chapter 4 - Data and Event HandlingWebStackAcademy
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js ExpressEyal Vardi
 
Introduction to .NET Core
Introduction to .NET CoreIntroduction to .NET Core
Introduction to .NET CoreMarco Parenzan
 
Angular - Chapter 1 - Introduction
 Angular - Chapter 1 - Introduction Angular - Chapter 1 - Introduction
Angular - Chapter 1 - IntroductionWebStackAcademy
 
Asp.Net Core MVC with Entity Framework
Asp.Net Core MVC with Entity FrameworkAsp.Net Core MVC with Entity Framework
Asp.Net Core MVC with Entity FrameworkShravan A
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous JavascriptGarrett Welson
 
Dot net platform and dotnet core fundamentals
Dot net platform and dotnet core fundamentalsDot net platform and dotnet core fundamentals
Dot net platform and dotnet core fundamentalsLalit Kale
 
Angular tutorial
Angular tutorialAngular tutorial
Angular tutorialRohit Gupta
 
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...Edureka!
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
ASP.NET MVC.
ASP.NET MVC.ASP.NET MVC.
ASP.NET MVC.Ni
 
Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1Mindfire Solutions
 
An introduction to React.js
An introduction to React.jsAn introduction to React.js
An introduction to React.jsEmanuele DelBono
 
Introduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectIntroduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectJadson Santos
 

What's hot (20)

Spring MVC Framework
Spring MVC FrameworkSpring MVC Framework
Spring MVC Framework
 
Angular 9
Angular 9 Angular 9
Angular 9
 
Angular - Chapter 4 - Data and Event Handling
 Angular - Chapter 4 - Data and Event Handling Angular - Chapter 4 - Data and Event Handling
Angular - Chapter 4 - Data and Event Handling
 
Node.js Express
Node.js  ExpressNode.js  Express
Node.js Express
 
Introduction to .NET Core
Introduction to .NET CoreIntroduction to .NET Core
Introduction to .NET Core
 
Angular - Chapter 1 - Introduction
 Angular - Chapter 1 - Introduction Angular - Chapter 1 - Introduction
Angular - Chapter 1 - Introduction
 
Vue.js
Vue.jsVue.js
Vue.js
 
Asp.Net Core MVC with Entity Framework
Asp.Net Core MVC with Entity FrameworkAsp.Net Core MVC with Entity Framework
Asp.Net Core MVC with Entity Framework
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
Dot net platform and dotnet core fundamentals
Dot net platform and dotnet core fundamentalsDot net platform and dotnet core fundamentals
Dot net platform and dotnet core fundamentals
 
Angular tutorial
Angular tutorialAngular tutorial
Angular tutorial
 
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js +  Expres...
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Node js
Node jsNode js
Node js
 
ASP.NET MVC.
ASP.NET MVC.ASP.NET MVC.
ASP.NET MVC.
 
Spring boot
Spring bootSpring boot
Spring boot
 
Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1Asynchronous Programming in C# - Part 1
Asynchronous Programming in C# - Part 1
 
An introduction to React.js
An introduction to React.jsAn introduction to React.js
An introduction to React.js
 
Introduction to angular with a simple but complete project
Introduction to angular with a simple but complete projectIntroduction to angular with a simple but complete project
Introduction to angular with a simple but complete project
 

Viewers also liked

Improving the Design of Existing Software
Improving the Design of Existing SoftwareImproving the Design of Existing Software
Improving the Design of Existing SoftwareSteven Smith
 
Introduction to ASP.NET Core
Introduction to ASP.NET CoreIntroduction to ASP.NET Core
Introduction to ASP.NET CoreAvanade Nederland
 
Asp.Net 2.0 Presentation
Asp.Net 2.0 PresentationAsp.Net 2.0 Presentation
Asp.Net 2.0 Presentationsasidhar
 
What's New in ASP.NET Core 2.0
What's New in ASP.NET Core 2.0What's New in ASP.NET Core 2.0
What's New in ASP.NET Core 2.0Jon Galloway
 
Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...
Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...
Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...Renato Groff
 
ASP.NET Core 2.0: The Future of Web Apps
ASP.NET Core 2.0: The Future of Web AppsASP.NET Core 2.0: The Future of Web Apps
ASP.NET Core 2.0: The Future of Web AppsShahed Chowdhuri
 

Viewers also liked (6)

Improving the Design of Existing Software
Improving the Design of Existing SoftwareImproving the Design of Existing Software
Improving the Design of Existing Software
 
Introduction to ASP.NET Core
Introduction to ASP.NET CoreIntroduction to ASP.NET Core
Introduction to ASP.NET Core
 
Asp.Net 2.0 Presentation
Asp.Net 2.0 PresentationAsp.Net 2.0 Presentation
Asp.Net 2.0 Presentation
 
What's New in ASP.NET Core 2.0
What's New in ASP.NET Core 2.0What's New in ASP.NET Core 2.0
What's New in ASP.NET Core 2.0
 
Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...
Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...
Implementando APIs multiplataforma com ASP.NET Core 2.0 - Nerdzão Day #3 - No...
 
ASP.NET Core 2.0: The Future of Web Apps
ASP.NET Core 2.0: The Future of Web AppsASP.NET Core 2.0: The Future of Web Apps
ASP.NET Core 2.0: The Future of Web Apps
 

Similar to Introducing ASP.NET Core 2.0

ASP.NET Core 1.0
ASP.NET Core 1.0ASP.NET Core 1.0
ASP.NET Core 1.0Ido Flatow
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoasZeid Hassan
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundryrajdeep
 
Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteorSapna Upreti
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsShahed Chowdhuri
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSGunnar Hillert
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Fwdays
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsShahed Chowdhuri
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsShahed Chowdhuri
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'sAntônio Roberto Silva
 
ASP.NET Presentation
ASP.NET PresentationASP.NET Presentation
ASP.NET PresentationRasel Khan
 
Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample ChapterSyed Shahul
 
SoCal Code Camp 2011 - ASP.NET MVC 4
SoCal Code Camp 2011 - ASP.NET MVC 4SoCal Code Camp 2011 - ASP.NET MVC 4
SoCal Code Camp 2011 - ASP.NET MVC 4Jon Galloway
 
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...OdessaJS Conf
 
How to Webpack your Django!
How to Webpack your Django!How to Webpack your Django!
How to Webpack your Django!David Gibbons
 

Similar to Introducing ASP.NET Core 2.0 (20)

ASP.NET Core 1.0
ASP.NET Core 1.0ASP.NET Core 1.0
ASP.NET Core 1.0
 
Rest web service_with_spring_hateoas
Rest web service_with_spring_hateoasRest web service_with_spring_hateoas
Rest web service_with_spring_hateoas
 
Play Support in Cloud Foundry
Play Support in Cloud FoundryPlay Support in Cloud Foundry
Play Support in Cloud Foundry
 
Reactive application using meteor
Reactive application using meteorReactive application using meteor
Reactive application using meteor
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
C#on linux
C#on linuxC#on linux
C#on linux
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web Apps
 
Modular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJSModular Test-driven SPAs with Spring and AngularJS
Modular Test-driven SPAs with Spring and AngularJS
 
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
Maciej Treder "Server-side rendering with Angular—be faster and more SEO, CDN...
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web Apps
 
Asp.net mvc
Asp.net mvcAsp.net mvc
Asp.net mvc
 
Owin and Katana
Owin and KatanaOwin and Katana
Owin and Katana
 
ASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web AppsASP.NET Core 2.1: The Future of Web Apps
ASP.NET Core 2.1: The Future of Web Apps
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
ASP.NET Presentation
ASP.NET PresentationASP.NET Presentation
ASP.NET Presentation
 
Spring Live Sample Chapter
Spring Live Sample ChapterSpring Live Sample Chapter
Spring Live Sample Chapter
 
DevRock #01 What's new ASP.net 5
DevRock #01 What's new ASP.net 5DevRock #01 What's new ASP.net 5
DevRock #01 What's new ASP.net 5
 
SoCal Code Camp 2011 - ASP.NET MVC 4
SoCal Code Camp 2011 - ASP.NET MVC 4SoCal Code Camp 2011 - ASP.NET MVC 4
SoCal Code Camp 2011 - ASP.NET MVC 4
 
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
Maciej Treder ''Angular Universal - a medicine for the Angular + SEO/CDN issu...
 
How to Webpack your Django!
How to Webpack your Django!How to Webpack your Django!
How to Webpack your Django!
 

More from Steven Smith

Clean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by ArdalisClean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by ArdalisSteven Smith
 
Finding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design PatternsFinding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design PatternsSteven Smith
 
Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018Steven Smith
 
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018Steven Smith
 
Introducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashIntroducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashSteven Smith
 
Most Useful Design Patterns
Most Useful Design PatternsMost Useful Design Patterns
Most Useful Design PatternsSteven Smith
 
Decoupling with Domain Events
Decoupling with Domain EventsDecoupling with Domain Events
Decoupling with Domain EventsSteven Smith
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016Steven Smith
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Steven Smith
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingSteven Smith
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing SoftwareSteven Smith
 
A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5Steven Smith
 
My Iraq Experience
My Iraq ExperienceMy Iraq Experience
My Iraq ExperienceSteven Smith
 
Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?Steven Smith
 
Domain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVCDomain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVCSteven Smith
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingSteven Smith
 
Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing SoftwareSteven Smith
 

More from Steven Smith (20)

Clean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by ArdalisClean architecture with asp.net core by Ardalis
Clean architecture with asp.net core by Ardalis
 
Finding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design PatternsFinding Patterns in the Clouds - Cloud Design Patterns
Finding Patterns in the Clouds - Cloud Design Patterns
 
Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018Introducing domain driven design - dogfood con 2018
Introducing domain driven design - dogfood con 2018
 
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
Design Pattern Mastery - Momentum Dev Con 19 Apr 2018
 
Introducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemashIntroducing Domain Driven Design - codemash
Introducing Domain Driven Design - codemash
 
Most Useful Design Patterns
Most Useful Design PatternsMost Useful Design Patterns
Most Useful Design Patterns
 
Decoupling with Domain Events
Decoupling with Domain EventsDecoupling with Domain Events
Decoupling with Domain Events
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
Breaking Dependencies to Allow Unit Testing - DevIntersection Spring 2016
 
Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016Improving the Quality of Existing Software - DevIntersection April 2016
Improving the Quality of Existing Software - DevIntersection April 2016
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
Improving the Quality of Existing Software
Improving the Quality of Existing SoftwareImproving the Quality of Existing Software
Improving the Quality of Existing Software
 
A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5A Whirldwind Tour of ASP.NET 5
A Whirldwind Tour of ASP.NET 5
 
Domain events
Domain eventsDomain events
Domain events
 
My Iraq Experience
My Iraq ExperienceMy Iraq Experience
My Iraq Experience
 
Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?Add Some DDD to Your ASP.NET MVC, OK?
Add Some DDD to Your ASP.NET MVC, OK?
 
Domain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVCDomain-Driven Design with ASP.NET MVC
Domain-Driven Design with ASP.NET MVC
 
Breaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit TestingBreaking Dependencies to Allow Unit Testing
Breaking Dependencies to Allow Unit Testing
 
Improving The Quality of Existing Software
Improving The Quality of Existing SoftwareImproving The Quality of Existing Software
Improving The Quality of Existing Software
 

Recently uploaded

In-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsIn-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsExpeed Software
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKUXDXConf
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekCzechDreamin
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1DianaGray10
 
Agentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdfAgentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdfChristopherTHyatt
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyJohn Staveley
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...CzechDreamin
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backElena Simperl
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101vincent683379
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
 
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀DianaGray10
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераMark Opanasiuk
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoTAnalytics
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty SecureFemke de Vroome
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Julian Hyde
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaRTTS
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessUXDXConf
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxDavid Michel
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxAbida Shariff
 

Recently uploaded (20)

In-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT ProfessionalsIn-Depth Performance Testing Guide for IT Professionals
In-Depth Performance Testing Guide for IT Professionals
 
Connecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAKConnecting the Dots in Product Design at KAYAK
Connecting the Dots in Product Design at KAYAK
 
AI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří KarpíšekAI revolution and Salesforce, Jiří Karpíšek
AI revolution and Salesforce, Jiří Karpíšek
 
UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1UiPath Test Automation using UiPath Test Suite series, part 1
UiPath Test Automation using UiPath Test Suite series, part 1
 
Agentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdfAgentic RAG What it is its types applications and implementation.pdf
Agentic RAG What it is its types applications and implementation.pdf
 
Demystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John StaveleyDemystifying gRPC in .Net by John Staveley
Demystifying gRPC in .Net by John Staveley
 
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
SOQL 201 for Admins & Developers: Slice & Dice Your Org’s Data With Aggregate...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101AI presentation and introduction - Retrieval Augmented Generation RAG 101
AI presentation and introduction - Retrieval Augmented Generation RAG 101
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
 
Intro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджераIntro in Product Management - Коротко про професію продакт менеджера
Intro in Product Management - Коротко про професію продакт менеджера
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
ECS 2024 Teams Premium - Pretty Secure
ECS 2024   Teams Premium - Pretty SecureECS 2024   Teams Premium - Pretty Secure
ECS 2024 Teams Premium - Pretty Secure
 
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
Measures in SQL (a talk at SF Distributed Systems meetup, 2024-05-22)
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Structuring Teams and Portfolios for Success
Structuring Teams and Portfolios for SuccessStructuring Teams and Portfolios for Success
Structuring Teams and Portfolios for Success
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 

Introducing ASP.NET Core 2.0

  • 1. No Content Here (Reserved for Watermark) Introducing ASP.NET Core 2.0 @ardalis Ardalis.com Steve Smith (in about an hour)
  • 2. No Content Here (Reserved for Watermark) No Content Here (Reserved for Watermark) Weekly Dev Tips Podcast and Newsletter • Ardalis.com/tips • WeeklyDevTips.com
  • 3. No Content Here (Reserved for Watermark) Being updated for 2.0 – should be done this month https://www.microsoft.com/net/learn/architecture See also AspNetCoreQuickstart.com online course Contact me for team training and/or mentoring Free eBook and Sample
  • 4. No Content Here (Reserved for Watermark) Agenda – My ASP.NET Core Top 10 List 1. Why ASP.NET Core? 2. Using the CLI 3. Startup 4. Managing Dependencies 5. Managing Middleware 6. ASP.NET Core MVC and Web APIs 7. Tag Helpers 8. Razor Pages 9. Testing ASP.NET Core 10. What’s New in 2.0 Full online course w/demos at: AspNetCoreQuickstart.com
  • 5. No Content Here (Reserved for Watermark) ASP.NET Core – What is it? A new open-source and cross-platform framework for building modern cloud-based Web applications using .NET
  • 6. No Content Here (Reserved for Watermark) Modular – NuGet Package-based Cloud and Container Optimized – Smaller memory footprint Open-Source with Contributions – even the docs Fast! - 8x Faster than Node; 3x Faster than Go Cross-Platform – Windows, Mac, Linux Choice of Tools and Editors – Any Text Editor plus CLI, or Visual Studio Goals
  • 7. No Content Here (Reserved for Watermark) Install SDK https://www.microsoft.com/net/download/core Optional: Install Visual Studio 2017 Install VS2017 .NET Core 2.0 Tools Confirm Version: Getting the Bits
  • 8. No Content Here (Reserved for Watermark) Visual Studio .NET Core Templates Console App Class Library Unit Test xUnit Test ASP.NET Core
  • 9. No Content Here (Reserved for Watermark) ASP.NET Core Project Templates Empty Web API Web App Web App (MVC) Angular React React and Redux Docker
  • 10. No Content Here (Reserved for Watermark) New Web Projects with dotnet dotnet new web Empty Hello World Project dotnet new mvc MVC Template --auth Individual adds identity support --use-local-db true uses localdb instead of SQLite dotnet new webapi dotnet new razorpages dotnet new angular | react | reactredux Use --help to view options in CLI
  • 11. No Content Here (Reserved for Watermark) dotnet CLI Templates
  • 12. No Content Here (Reserved for Watermark) dotnet new razor
  • 13. No Content Here (Reserved for Watermark) Razor Pages Convention-Based Routes No Controllers; No Actions PageModel as Codebehind Handlers replace Actions PageModel as ViewModel Leverages existing MVC features Model Binding / Validation Routing Filters Maintains Testability and Separation of Concerns More in my Razor Pages article in September 2017 MSDN Magazine
  • 14. No Content Here (Reserved for Watermark) Section Program.cs ASP.NET Core Startup
  • 15. No Content Here (Reserved for Watermark) var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build(); host.Run(); WebHostBuilder (1.x)
  • 16. No Content Here (Reserved for Watermark) public class Program { public static void Main(string[] args) { BuildWebHost(args).Run(); } public static IWebHost BuildWebHost(string[] args) => WebHost.CreateDefaultBuilder(args) .UseStartup<Startup>() .Build(); } WebHostBuilder (2.x)
  • 17. No Content Here (Reserved for Watermark) using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; class Program { static void Main(string[] args) { new WebHostBuilder() .UseKestrel() .Configure(a => a.Run(c => c.Response.WriteAsync("Hi!"))) .Build() .Run(); } } A Minimal ASP.NET Core App
  • 18. No Content Here (Reserved for Watermark) using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore; public class Program { public static void Main() { WebHost.CreateDefaultBuilder() .Configure(app => app.Run(async (context) => { await context.Response.WriteAsync("Hello World!"); })) .Build() .Run(); } } A Minimal ASP.NET Core App (2.0)
  • 19. No Content Here (Reserved for Watermark)
  • 20. No Content Here (Reserved for Watermark) Section Startup.cs ASP.NET Core Startup
  • 21. No Content Here (Reserved for Watermark) Startup Constructor (optional) ConfigureServices Configure
  • 22. No Content Here (Reserved for Watermark) Constructor (optional) Inject Dependencies (needed by Startup) Set up configuration (done by default in 2.0) Set up Startup logging (done by default in 2.0)
  • 23. No Content Here (Reserved for Watermark) public Startup(IHostingEnvironment env) { var builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true); if (env.IsDevelopment()) { builder.AddUserSecrets<Startup>(); } builder.AddEnvironmentVariables(); Configuration = builder.Build(); } Startup Constructor (1.x)
  • 24. No Content Here (Reserved for Watermark) public Startup(IConfiguration configuration) { Configuration = configuration; } Startup Constructor (2.0)
  • 25. No Content Here (Reserved for Watermark) Startup ConfigureServices Add framework services needed by app to services collection Add application services to services collection Optional Configure Options used by app components Configure third-party container StructureMap, Unity, Autofac, Ninject, Castle Windsor, etc.
  • 26. No Content Here (Reserved for Watermark) public void ConfigureServices(IServiceCollection services) { services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))); services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders(); services.AddMvc(); services.AddSingleton<IEmailSender, EmailSender>(); } Startup ConfigureServices (2.0)
  • 27. No Content Here (Reserved for Watermark) public IServiceProvider ConfigureServices(IServiceCollection services) { services.AddDbContext<AppDbContext>(options => options.UseInMemoryDatabase(Guid.NewGuid().ToString())); services.AddMvc(); var container = new Container(); container.Configure(config => { config.Scan(_ => { _.AssemblyContainingType(typeof(Startup)); // Web _.WithDefaultConventions(); }); config.For(typeof(IRepository<>)).Add(typeof(EfRepository<>)); config.Populate(services); }); return container.GetInstance<IServiceProvider>(); } Custom DI Container (Structuremap)
  • 28. No Content Here (Reserved for Watermark) Startup.Configure Configure the application request pipeline Configure and arrange middleware Optional Configure logging for the application (done here by convention in 1.x; not required here in 2.x)
  • 29. No Content Here (Reserved for Watermark) public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); app.UseBrowserLink(); app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Error"); } app.UseStaticFiles(); app.UseAuthentication(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller}/{action=Index}/{id?}"); }); } Startup Configure (2.0)
  • 30. No Content Here (Reserved for Watermark) Section Built-in and Custom Middleware Middleware
  • 31. No Content Here (Reserved for Watermark) “Middleware are software components that are assembled into an application pipeline to handle requests and responses” Each component in the pipeline is a request delegate. Each delegate can invoke the next component in the chain, or short-circuit, returning back up the call chain What is Middleware?
  • 32. No Content Here (Reserved for Watermark)
  • 33. No Content Here (Reserved for Watermark) public void Configure(IApplicationBuilder app) { // app.Run terminates the pipeline without calling any later middleware app.Run(async context => { await context.Response.WriteAsync("Hello, World!"); }); } Creating Middleware in Startup: Run
  • 34. No Content Here (Reserved for Watermark) public void Configure(IApplicationBuilder app) { // app.Use can execute code before and after other middleware app.Use(async (context, next) => { // do some work // call the next middleware await next.Invoke(); // do some additional work }); } Creating Middleware in Startup: Use
  • 35. No Content Here (Reserved for Watermark) public void Configure(IApplicationBuilder app) { // app.Map can map a path to a function app.Map(“hello”, HandleHello); app.Run(async context => { await context.Response.WriteAsync(“Invalid path!"); }); } public void HandleHello(IApplicationBuilder app) { app.Run(async context => { await context.Response.WriteAsync(“Hello!"); }); } Creating Middleware in Startup: Map
  • 36. No Content Here (Reserved for Watermark) public class MyMiddleware { private readonly RequestDelegate _next; public MyMiddleware(RequestDelegate next) { _next = next; } public Task Invoke(HttpContext httpContext) { return _next(httpContext); } } // Extension method used to add the middleware to the HTTP request pipeline. public static class MyMiddlewareExtensions { public static IApplicationBuilder UseMyMiddleware(this IApplicationBuilder builder) { return builder.UseMiddleware<MyMiddleware>(); } } Moving Middleware to its own classes
  • 37. No Content Here (Reserved for Watermark) Built-in Middleware : Diagnostics UseDeveloperExceptionPage UseDatabaseErrorPage – helps configure database UseBrowserLink UseExceptionHandler UseStatusCodePages UseWelcomePage UseElmPage / UseElmCapture (preview)
  • 38. No Content Here (Reserved for Watermark) Built-in Middleware UseIdentity (UseAuthentication in 2.0) UseStaticFiles UseDefaultFiles UseDirectoryBrowser (requires services) UseFileServer (replaces/combines previous three) UseRouter UseMvc (replaces/wraps UseRouter; requires services) UseRewriter (1.1) UseResponseCompression (1.1) UseResponseCaching (1.1, requires services)
  • 39. No Content Here (Reserved for Watermark) Project Dependencies (1.x)
  • 40. No Content Here (Reserved for Watermark) New Project Dependencies (2.0)
  • 41. No Content Here (Reserved for Watermark) <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.0</TargetFramework> <UserSecretsId>aspnet-NewIn2-718CDB27-A711-46D2-8222-38EB73FC1D4B</UserSecretsId> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.0.0" PrivateAssets="All" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.0" PrivateAssets="All" /> </ItemGroup> <ItemGroup> <DotNetCliToolReference Include="Microsoft.EntityFrameworkCore.Tools.DotNet" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.Extensions.SecretManager.Tools" Version="2.0.0" /> <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.0" /> </ItemGroup> <ItemGroup> <ProjectReference Include="..NewIn2.CoreNewIn2.Core.csproj" /> </ItemGroup> </Project> Typical Project File (2.x)
  • 42. No Content Here (Reserved for Watermark) Section Keeping Code Modular and Loosely Coupled Injecting Dependencies in ASP.NET Core
  • 43. No Content Here (Reserved for Watermark) Dependency Injection (DI) Classes request dependencies instead of referencing directly Dependent object instances are injected as parameters (or properties) Allows for flexibility and modularity Classes follow Explicit Dependencies Principle, Dependency Inversion Principle
  • 44. No Content Here (Reserved for Watermark) Explicit Dependencies Principle Classes should express their requirements through their constructor Direct use of specific collaborators creates hidden dependencies Classes with hidden dependencies aren’t “honest” about what they require Constructor should be a contract that specifies what the class requires Learn more: http://deviq.com/explicit-dependencies-principle/
  • 45. No Content Here (Reserved for Watermark) Section ASP.NET Core MVC (and Web APIs – they are ONE THING now!)
  • 46. No Content Here (Reserved for Watermark) Controllers and Actions Controllers are collections of actions Useful for grouping actions into cohesive sets Used by default for routing and URL generation (e.g. /{controllername}/{actioname}) Actions are methods that handle individual requests Each request is routed to an action method
  • 47. No Content Here (Reserved for Watermark) An MVC Action
  • 48. No Content Here (Reserved for Watermark) public async Task OnGetAsync(string returnUrl = null) { if (!string.IsNullOrEmpty(ErrorMessage)) { ModelState.AddModelError(string.Empty, ErrorMessage); } ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()) .ToList(); ReturnUrl = returnUrl; } Razor Pages Entry Point
  • 49. No Content Here (Reserved for Watermark) Routing to Actions Default route specified in Startup Configure method Attribute routing (at Controller and/or Action level) [Route(“products/index”)] [Route(“products/update/{id})] [Route(“home”)] on Controller and [Route(“about”)] on Action are combined into “home/about” route
  • 50. No Content Here (Reserved for Watermark) Attribute Routing Tips Use default convention where possible Define routes using attributes for non-default cases, especially for APIs APIs should use HTTP verb attributes to define routes: [HttpGet] [HttpGet(“{id}”)] // will combine with route specified on controller Routes can use token replacement for [area], [controller], [action]: [Route(“[controller]/[action]”)] Especially powerful when used with inheritance: [Route(“api/[controller]/[action]”)] public abstract class BaseApiController : Controller
  • 51. No Content Here (Reserved for Watermark) Accepting Data in Actions (Model Binding) MVC uses model binding to convert data sent by requests into action parameters Model binding takes place before the action is invoked Parameters may be simple types, or complex objects Data can come from named form values, route components, or query strings
  • 52. No Content Here (Reserved for Watermark) Model Validation Model types can have validation rules specified Actions should check model validation state before making changes to application state if(ModelState.IsValid) Avoid using data model types for model binding This can result in exposing more data to user changes than intended Use [FromBody] to bind to data in the body of the request (JSON by default) Use [BindProperty] to bind properties to non-GET requests (2.0)
  • 53. No Content Here (Reserved for Watermark) Tag Helpers Replaces HTML Helpers (still available, but not recommended) Render within HTML tags Declarative, not Imperative
  • 54. No Content Here (Reserved for Watermark) Tag Helper Example
  • 55. No Content Here (Reserved for Watermark) Tag Helper Example
  • 56. No Content Here (Reserved for Watermark) Working With a Database Using EF Core Add Entity Framework Core (EF Core) in ConfigureServices: Also supports InMemory – Install this package: and modify ConfigureServices: services.AddDbContext<AppDbContext>(options => options.UseInMemoryDatabase(“DbName”)); //options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
  • 57. No Content Here (Reserved for Watermark) Working with EF Core’s AppDbContext Never directly instantiate your application’s DbContext type(s) Instead, request from DI using constructor parameters Recommendation Follow the Dependency Inversion Principle and avoid having UI types depend on details Using Entity Framework Core is an implementation detail Instead depend on an abstraction over your persistence method Common pattern for this: Repository
  • 58. No Content Here (Reserved for Watermark) Section Testing ASP.NET Core Apps One of my favorite new features!
  • 59. No Content Here (Reserved for Watermark) Configuring a TestServer Use a WebHostBuilder Configure like in your web project Modify for testing if necessary Create a TestServer from this builder instance Create an HttpClient using CreateClient() Make requests to the app using the client instance
  • 60. No Content Here (Reserved for Watermark) Functional Testing ASP.NET Core Apps Make a request using the HttpClient instance Capture the response Verify status code Deserialize if necessary Assert that the result included the values you expected APIs are easy; views require a little more work to configure for testing
  • 61. No Content Here (Reserved for Watermark) [Fact] public async Task ReturnTwoItems() { var response = await _client.GetAsync("/api/todoitems"); response.EnsureSuccessStatusCode(); var stringResponse = await response.Content.ReadAsStringAsync(); var result = JsonConvert.DeserializeObject<IEnumerable<ToDoItem>> (stringResponse).ToList(); Assert.Equal(2, result.Count()); Assert.Equal(1, result.Count(a => a.Title == "Test Item 1")); Assert.Equal(1, result.Count(a => a.Title == "Test Item 2")); } A Functional Test
  • 62. No Content Here (Reserved for Watermark) protected HttpClient GetClient() { var builder = new WebHostBuilder() .UseContentRoot(Directory.GetCurrentDirectory()) .UseStartup<Startup>() .UseEnvironment("Testing"); // ensure ConfigureTesting is called in Startup var server = new TestServer(builder); var client = server.CreateClient(); // client always expects json results client.DefaultRequestHeaders.Clear(); client.DefaultRequestHeaders.Accept.Add( new MediaTypeWithQualityHeaderValue("application/json")); return client; } Configurating the Client
  • 63. No Content Here (Reserved for Watermark) Runtime Store – Precompiles meta-package and eliminates need to deploy its packages .NET Standard 2.0 – Much larger BCL available cross-platform DI-Enabled Authentication Kestrel improvements – now supports edge (Internet-facing) deployment Hosting environment can inject dependencies and code into apps Automatic CSRF protection Automatic Razor view compilation New Tag Helper Components IHostedService – start/stop services when application starts/stops VB support (console, class libraries) EF Core Owned Entities, Global filters, DbContext Pooling More New Stuff in 2.0
  • 64. No Content Here (Reserved for Watermark) Demonstration Razor Pages and EF Core New Features
  • 65. No Content Here (Reserved for Watermark) Migration from 1.x to 2.0 Tips 1. Update TargetFramework to netcoreapp2.0 2. Update global.json to version 2.0.0 (if used) 3. Update package references. Use new MS.AspNetCore.All 2.0.0 package. Includes EF Core 2.0. 4. Update other packages to 2.0.0 if needed. 5. Update .NET Core CLI Tools 6. Change PackageTargetFallback to AssetTargetFallback 7. Update Main in Program.cs 8. Make sure you're not doing DB setup in Startup.Configure. Move it to Main in Program.cs. 9. Remove MvcRazorCompileOnPublish = true from .csproj files -- it is now on by default. If targeting .NET Framework, need to reference ViewCompilation package. 10. If you're not explicitly using App Insights, remove from .csproj, program.cs, and your _Layout file. 11. Migrate Auth/Identity to 2.0
  • 66. No Content Here (Reserved for Watermark) ASP.NET Core is the future of Microsoft’s platform Lots of cool demos I didn’t have time to show. Check out AspNetCoreQuickstart.com Use qltechcon2017 for 20% off Subscribe to WeeklyDevTips.com Connect with me on Twitter: @ardalis Thanks! Summary

Editor's Notes

  1. Almost all ASP.NET apps use a standard Startup class to configure how the app will work. ASP.NET Core apps run inside of a web host, and even before Startup is called, a WebHostBuilder is used to create a host that then runs.
  2. Most ASP.NET Core project templates include a Program.cs file, which holds a public static void Main entry point for the app. It’s where the web host is built and run. You don’t actually need a Startup class at all to create an ASP.NET Core app – you can perform all of the configuration inside of WebHostBuilder if you want.
  3. Using WebHostBuilder, which isn’t strictly required.
  4. Almost all ASP.NET apps use a standard Startup class to configure how the app will work. ASP.NET Core apps run inside of a web host, and even before Startup is called, a WebHostBuilder is used to create a host that then runs.
  5. Using the built-in container…
  6. Note that Startup is not a strongly typed contract. Methods can have arbitrary signatures and some support different return types.
  7. Logging is no longer done here. Data seeding should not be done here, since migrations run after this.
  8. Your ASP.NET Core app’s request pipeline is composed of components called middleware. ASP.NET Core ships with a bunch of useful middleware that your apps can use, and it’s pretty straightforward to create your own.
  9. For most apps, you won’t have to write any middleware yourself. You’ll probably use a higher-level framework, like MVC, and some of the built-in middleware that ships with ASP.NET Core. There are several interesting pieces of middleware that are very useful when developing your app. The DeveloperExceptionPage will let you see details about exceptions that are unhandled by your app. You don’t want this to be enabled in production, as it could reveal sensitive data, but it’s great during development. The DatabaseErrorPage is helpful when you’re first creating an app and haven’t yet configured its database. It can help you get that set up. BrowserLink works with Visual Studio to speed up how quickly changes you make in your app are reflected in the browser, without always have to restart the app and refresh the browser. You can specify an Exception Handler route, so that any unhandled exceptions that occur result in the display of an “oops” or similar page for users in production. If you want custom pages for certain status codes, such as a humorous 404 Not Found page, the UseStatusCodePages middleware can provide this functionality. The Welcome pages provide some very basic information, and is useful for ensuring the app is functioning at its most basic level Finally, the ElmPage and ElmCapture middleware are part of the Error Logging Middleware, or ELM, which can be used to record developer exception pages for later review.
  10. UseIdentity is used to allow your app to use the built-in membership and identity services. It’s used with authentication and authorization. Static files middleware is required for the app to server up static content, such as script and style files, and images. Some apps may require additional file serving functionality, in which case you can add support for default files, like default.aspx or index.htm. You can configure the app to act as a server-side file browser, and if you need all of this functionality you can simply add the FileServer middleware. If you need to customize routes and routing in your app, you can use Router middleware. Most apps will work at a higher level than this, though, such as with the Model View Controller, or MVC framework, which uses Router internally. Version 1.1 of ASP.NET Core added some additional middleware to support URL rewriting, response compression, and response caching.
  11. ASP.NET Core doesn’t just support dependency injection, it uses it internally to achieve its goals of being modular and loosely coupled. Your application code can leverage this capability in the same way ASP.NET Core does.
  12. Dependency injection, or DI, is a software design technique in which collaborating classes are injected into the class that needs them, rather than being referenced directly. One could even call it collaborator injection. The collaborator, or dependency, is injected into the class by way of parameters, or sometimes by setting properties. The most common technique involves passing the dependencies into the constructor of the class that will need them, which then assigns the instances to local fields. This approach produces a more flexible and modular design, since classes do not have direct dependence on specific implementations of their collaborators. This also ensure the classes follow the Explicit Dependencies Principle and the Dependency Inversion Principle.
  13. The Explicit Dependencies Principle states that classes should express their requirements through their constructor. If the class cannot function without certain collaborating classes being available, then it should be up front about these dependencies and request them as part of its constructor. If instead the class directly instantiates its dependencies, or references them statically, it creates hidden dependencies and tight coupling that may only become apparent at runtime. For example, if you have a class that interacts with a database, and it does so by calling a static helper method, it’s likely this class will fail with an exception at runtime if the database isn’t available. However, if you’re interested in testing the behavior of the class, perhaps swapping in a fake database or using an in memory data store instead for test purposes, it will be very difficult to do so when the dependency is implicit within the class and not exposed as a parameter. This can also be an example of violating the Open/Closed Principle, because the class’s behavior could not be changed without changing its source code. Classes that have hidden or implicit dependencies aren’t being honest about their functional requirements. If the class or method needs a database (or some data store) in order to function, it should declare this dependency as a parameter. If only one method has a dependency, it may make sense to only add the parameter at the method rather than the class level. However, many frameworks provide support for automatically populating dependencies on the constructor, so even in the case where only one method has a dependency, it may make sense to inject it through the class constructor.
  14. At the end of the last chapter, we created a simple MVC app and looked at how we can use ASP.NET Core’s dependency injection feature to inject services into controllers. In this chapter, we’ll provide an overview of ASP.NET Core MVC that should let you get started building business apps on top of this framework. This will include building Web APIs with ASP.NET Core MVC. In ASP.NET MVC 5 and Web API 2, support for web APIs was in a separate set of classes and packages from MVC. In ASP.NET Core, this is no longer the case, and web API functionality is built directly into ASP.NET Core MVC.
  15. The entry point for each request to your ASP.NET Core MVC application is an action. Actions are methods, and collections of actions are grouped together into cohesive sets by Controllers. Controllers are useful for routing and URL generation, as well as to support constructor dependency injection. In ASP.NET Core MVC, controllers do not need to inherit from any special type – they just need to be named with the Controller suffix. However, the Microsoft.AspNetCore.Mvc.Controller type provides many helpful methods that you can use. Here you can see an example of a simple controller that inherits from the Controller base class and defines several action methods. Actions are simply methods that handle individual requests. Each request made to the application maps to an action method by way of routing middleware. Individual actions can return raw data, a view, or an action result. Actions can be synchronous or async. Here is an example of a simple async action that displays a view for a Login page in an application. Since it is async, its return type is a Task of IActionResult instead of just an IActionResult. It also uses the Await keyword in its body when it calls out to async methods. This action method is also decorated with two attributes. The first one, HttpGet, specifies the HTTP verb this action will respond to, and is used by the routing engine. The second attribute, AllowAnonymous, will override an attribute set at a higher level requiring the user to be authenticated, and will allow an anonymous request to run this action.
  16. You can specify default routes for MVC when you configure it in the Configure method in Startup. The default MVC templates add code like this, which defines a default route template. This template should be familiar to you if you’ve used MVC 5 or earlier. It uses the routing convention of controller/action/id, where id is optional. It also specifies default values for the controller and action, so if not present Home and Index are used. ASP.NET Core MVC supports attribute routing, which lets you define route information close to the actions that will use be associated with the route. The Route attribute is used to specify the route at the controller and/or action level, and if routes are specified for both they are combined.
  17. Here are my tips for working with routing in ASP.NET Core MVC. First, use the default route convention wherever possible. It works well and will be familiar to any developers who must work on your application later, whether they’re coming from Core MVC or legacy ASP.NET MVC. Embrace attribute routing and use it wherever you need to stray from the defaults. Microsoft especially recommends this for API methods. API method can define routes directly within their HTTP Verb attributes, so for instance you can specify a route or partial route as part of an [HttpGet] or [HttpPost] attribute. This action-level route will be combined with any controller-specified route. To reduce the number of magic strings you need to specify in your routes, you can use token replacements for area, controller, and action. These tokens will be replaced with the actual area, controller, or action name where the route attribute is applied. This feature is especially powerful when combined with inheritance. For example, if you want all of your API methods to use a route starting with /api and followed by controllername and actionname, you can specify this route attribute on a base api controller class, as shown.
  18. Clients, whether web browsers or other applications, can send data to your application as web requests. MVC uses a process called model binding to convert data sent by requests into parameters on action methods. Model binding takes place before the action is invoked. This is important to remember since occasionally there may be errors or other behavior going on during model binding that may not be immediately apparent to you if you’re expecting your action to be the first code to be executed by a request. Don’t forget about model binding! Parameters on action methods may be simple primitive types like ints and strings, or they may be complex objects. Model binding can support all of these scenarios. Data coming into an action may come from form values, route components, or query strings, in this order. Model types can also have validation rules specified, and model validation occurs before the action method is called. Your actions should always check model validity, especially in methods that will make changes to application state. You should avoid using data model types in your UI layer, but if you must, you should especially avoid using them in actions that accept data and use model binding. Doing so can allow malicious users to save properties you may not have meant to expose, because they could guess these properties exist, pass them into the request, and model binding will automatically populate these properties (which you might then save in your action). Finally, you can use the FromBody attribute on a single parameter to specify that it should be found to the body of the request. By default the expected format is JSON, but you can configure other input formatters to support formats like XML.
  19. Clients, whether web browsers or other applications, can send data to your application as web requests. MVC uses a process called model binding to convert data sent by requests into parameters on action methods. Model binding takes place before the action is invoked. This is important to remember since occasionally there may be errors or other behavior going on during model binding that may not be immediately apparent to you if you’re expecting your action to be the first code to be executed by a request. Don’t forget about model binding! Parameters on action methods may be simple primitive types like ints and strings, or they may be complex objects. Model binding can support all of these scenarios. Data coming into an action may come from form values, route components, or query strings, in this order. Model types can also have validation rules specified, and model validation occurs before the action method is called. Your actions should always check model validity, especially in methods that will make changes to application state. You should avoid using data model types in your UI layer, but if you must, you should especially avoid using them in actions that accept data and use model binding. Doing so can allow malicious users to save properties you may not have meant to expose, because they could guess these properties exist, pass them into the request, and model binding will automatically populate these properties (which you might then save in your action). Finally, you can use the FromBody attribute on a single parameter to specify that it should be found to the body of the request. By default the expected format is JSON, but you can configure other input formatters to support formats like XML.
  20. The default MVC project template in visual studio uses EF Core if you specify that you want to have individual user accounts. You’ll find a line of code in your startup class that adds support for EF Core to the app by adding it in the ConfigureServices method. This is where you specify your application’s DbContext class, which inherits from the base DbContext class defined by EF Core. You also specify how it will connect to Sql Server. EF Core has built-in support for an InMemory database provider. This support requires installing a separate package and modifying the configuration of your DbContext type as shown. You’ll probably also need to specify the Microsoft.EntityFrameworkCore namespace for the UseInMemoryDatabase extension method to work. The in-memory data store is reset each time the application starts.
  21. In your ASP.NET Core applications, you should never be instantiating your application’s DbContext implementation directly. This advice applies to previous MVC implementations, too, but it was much easier to instantiate an EF6 dbcontext than it is to instantiate an EF Core one. This is at least partly by design – in EF Core the team has embraced dependency injection and wants code to fall into this pattern by default. Thus, to make use of EF Core in your application, you should simply request your DbContext implementation from the constructor of the type that needs it. That said, you should also try to follow the Dependency Inversion Principle, which means you want to avoid having your UI types, like Controllers, depending on details. EF Core is an implementation detail for how your app gets and persists data. Rather than depending on it directly, your classes should depend on abstractions. The common pattern that describes these persistence abstractions is the Repository. You may hear some in the developer community decry this pattern, or say that it’s not needed because EF already implements this pattern. In my experience, not following this pattern will bit you later, and following it is simple and easy, so you’re better off following it. You’ll have more loosely coupled code that’s easier to change and test if you follow this recommendation.
  22. If you’re building an app of any complexity, you’ll probably get some value out of testing it so that you know it works as you expect. You can manually test your application, but your time is valuable and computers can do that sort of thing much faster than humans can, so why not automate it?
  23. One of my favorite features in ASP.NET Core is the TestServer. The TestServer makes it extremely easy to write integration tests for ASP.NET Core that run through the full ASP.NET Core MVC stack. You configure a TestServer using a WebHostBuilder. The configuration might look just like the builder you use for your application, but you can modify it if necessary to make it work for testing. For instance, you might want to change how it gets its data or configure it with test data your tests will expect. Once you have a WebHostbuilder configured, use it to create a TestServer instance, and then you can get an HttpClient from the TestServer. This HttpClient is pre-configured to connect to the TestServer, all of which happens without going through your system’s network stack, so you don’t run into issues with firewalls or other problems when using this approach. Once you have the client, you can use it to make requests to your application, and then verify the responses.
  24. To perform integration testing on ASP.NET core, get an HttpClient that connects to your TestServer, and make a request. Capture the response, and verify it’s correct. You can start by verifying that the status code was what you expected. Then deserialize the response, if required. The response will be a string. If you want to get it back into an object, you can deserialize it using JSON or XML or whatever format it’s in. For view-based responses, the result will typically be a string containing HTML. Assert that the response includes the values you’re expecting to complete your test. You’ll find using this approach that testing API methods if pretty easy. Testing views requires a little more setup initially, and the assertions on the results can be more brittle depending on how you specific you are about your assertion. We’ll look at both of these scenarios next.
  25. Migration Notes: https://docs.microsoft.com/en-us/aspnet/core/migration/1x-to-2x/index 1. Update TargetFramework to netcoreapp2.0 2. update global.json to version 2.0.0 (if used) 3. Update package references. Use new MS.AspNetCore.All 2.0.0 package. Includes EF Core 2.0. 4. Update other packages to 2.0.0 if needed. 5. Update .NET Core CLI Tools 6. Change PackageTargetFallback to AssetTargetFallback 7. Update Main in Program.cs 8. Make sure you're not doing DB setup in Startup.Configure. Move it to Main in Program.cs. 9. Remove MvcRazorCompileOnPublish = true from .csproj files -- it is now on by default. If targeting .NET Framework, need to reference ViewCompilation package. 10. If you're not explicitly using App Insights, remove from .csproj, program.cs, and your _Layout file. 11. Migrate Auth/Identity to 2.0