Academy PRO: ASP .NET Core

Post on 16-Apr-2017

68 views 2 download

transcript

ASP.NET Core

binary-studio.com

Contents

1. Intro

2. Startup

3. Middleware

4. Logging

5. Static files

6. Routing

7. Authentication

8. Configuration

9. Error handling

10.Swagger

Intro

What is ASP.NET Core?leaner and modular architecture

tighter security

reduced servicing

improved performance

pay-for-what-you-use model.

Why is ASP.NET Core?

Integration of modern client-side frameworks and development workflows

A cloud-ready environment-based configuration system

Built-in dependency injection

New light-weight and modular HTTP request pipeline (No System.Web.dll

Ability to host on IIS or self-host in your own process

Built on .NET Core, which supports true side-by-side app versioning

Ships entirely as NuGet packages

New tooling that simplifies modern web development

Build and run cross-platform ASP.NET apps on Windows, Mac and Linux

Open source and community focused

public static void Main(string[] args){ var host = new WebHostBuilder() .UseKestrel() // .UseServer("Microsoft.AspNet.Server.Kestrel") .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build();

host.Run();}

Startup

Configure - how the ASP.NET application will respond to individual HTTP requests.

ConfigureServices - method for configuring services that are used by your application.

Configurepublic void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){ loggerFactory.AddConsole(Configuration.GetSection("Logging")); loggerFactory.AddDebug();

if (!env.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); }

app.UseStaticFiles();

app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); });}

ConfigureServicespublic void ConfigureServices(IServiceCollection services){ // Add framework services. services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

services.AddIdentity<ApplicationUser, IdentityRole>() .AddEntityFrameworkStores<ApplicationDbContext>() .AddDefaultTokenProviders();

services.AddMvc();

// Add application services. services.AddTransient<IEmailSender, AuthMessageSender>(); services.AddTransient<ISmsSender, AuthMessageSender>();}

Middleware

Pipeline with IApplicationBuilderpublic void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory){ app.UseExceptionHandler("/Home/Error"); // Middleware 1 app.UseStaticFiles(); // Middleware 2

app.UseIdentity(); // Middleware 3

app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); // Middleware 4}

Custom pipelinepublic void ConfigureLogInline(IApplicationBuilder app, ILoggerFactory loggerfactory){ loggerfactory.AddConsole(minLevel: LogLevel.Information); var logger = loggerfactory.CreateLogger(_environment);

app.Use(async (context, next) => { logger.LogInformation("Handling request."); await next.Invoke(); // Comment it to terminate the pipeline logger.LogInformation("Finished handling request."); });

app.Run(async context => { await context.Response.WriteAsync("Hello from " + _environment); });}

Logging

Logging

Interfaces:

ILoggerFactory

ILogger

Extension methods:

AddConsole

AddDebug

AddTraceSource

Simple logging[Route("api/[controller]")]public class TodoController : Controller{ private readonly ITodoRepository _todoRepository; private readonly ILogger<TodoController> _logger;

public TodoController(ITodoRepository todoRepository, ILogger<TodoController> logger) { _todoRepository = todoRepository; _logger = logger; }

[HttpGet] public IEnumerable<TodoItem> GetAll() { _logger.LogInformation(LoggingEvents.LIST_ITEMS, "Listing all items"); return _todoRepository.GetAll(); }}

Thirdparty Providers

elmah.io - provider for the elmah.io service

Loggr - provider for the Loggr service

NLog - provider for the NLog library

Serilog - provider for the Serilog library

your own

Static Files

Set directory to content:

public static void Main(string[] args){

var host = new WebHostBuilder() .UseKestrel() .UseContentRoot(Directory.GetCurrentDirectory()) .UseIISIntegration() .UseStartup<Startup>() .Build();

host.Run();}

Set static files to pipeline:

public void Configure(IApplicationBuilder app,

IHostingEnvironment env, ILoggerFactory

loggerFactory)

{

app.UseStaticFiles();

app.UseStaticFiles(new StaticFileOptions()

{

FileProvider = new PhysicalFileProvider(

Path.Combine(Directory.GetCurrentDirectory(),

@"MyStaticFiles")),

RequestPath = new PathString("/StaticFiles")

});

}

Content type mappingpublic void Configure(IApplicationBuilder app)

{

// Set up custom content types -associating file extension to MIME type

var provider = new FileExtensionContentTypeProvider();

// Add new mappings

provider.Mappings[".myapp"] = "application/x-msdownload";

provider.Mappings[".htm3"] = "text/html";

provider.Mappings[".image"] = "image/png";

// Replace an existing mapping

provider.Mappings[".rtf"] = "application/x-msdownload";

// Remove MP4 videos.

provider.Mappings.Remove(".mp4");

app.UseStaticFiles(new StaticFileOptions() {

FileProvider = new PhysicalFileProvider(

Path.Combine(Directory.GetCurrentDirectory(), @"wwwroot\images")),

RequestPath = new PathString("/MyImages"),

ContentTypeProvider = provider

});

}

Routing

URL Matching

Request

Route 1Route 2Route N

RouterMiddleware

.RouteAsync()

Handle()

Next()

Mappingroutes.MapRoute(

name: "default",

template: "{controller=Home}/{action=Index}/{id?}");

routes.MapRoute(

name: "us_english_products",

template: "en-US/Products/{id}",

defaults: new { controller = "Products", action = "Details" },

constraints: new { id = new IntRouteConstraint() },

dataTokens: new { locale = "en-US" });

Routing Middlewarepublic void ConfigureServices(

IServiceCollection services)

{

services.AddRouting();

}

public void Configure(IApplicationBuilder app, ILoggerFactory

loggerFactory)

{

var trackPackageRouteHandler = new RouteHandler(context =>

{

var routeValues = context.GetRouteData().Values;

return context.Response.WriteAsync(

$"Hello! Route values: {string.Join(", ", routeValues)}");

});

var routeBuilder = new RouteBuilder(app, trackPackageRouteHandler);

routeBuilder.MapRoute(

"Track Package Route",

"package/{operation:regex(^track|create|detonate$)}/{id:int}");

routeBuilder.MapGet("hello/{name}", context =>

{

var name = context.GetRouteValue("name");

return context.Response.WriteAsync($"Hi, {name}!");

});

var routes = routeBuilder.Build();

app.UseRouter(routes);

Authentication

Identity// Authentication should be set to Individual User Accounts

// ConfigureServices

services.AddIdentity<ApplicationUser, IdentityRole>()

.AddEntityFrameworkStores<ApplicationDbContext>()

.AddDefaultTokenProviders();

// Configure

app.UserIdentity();

// Manage users

UserManager<ApplicationUser> _usermanager;

// Manage sign in/sign out

SignInManage<ApplicationUser> _signinmanager;

Facebook, Twitter, Google Providersapp.UseFacebookAuthentication(new FacebookOptions()

{

AppId = Configuration["Authentication:Facebook:AppId"],

AppSecret = Configuration["Authentication:Facebook:AppSecret"]

});

// Other providers use similar approach

Other Features

Two-factor authentication with SMS

Supporting Third Party Clients using OAuth 2.0

Azure Active Directory

Securing ASP.NET Core apps with IdentityServer4

Configuration

var builder = new ConfigurationBuilder();

builder.SetBasePath(Directory.GetCurrentDirectory());

builder.AddJsonFile("appsettings.json");

builder.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);

builder.AddCommandLine(args);

var connectionStringConfig = builder.Build();

var str = connectionStringConfig.GetConnectionString("DefaultConnection")

IOptions// ConfigureServicesservices.AddOptions();services.Configure<MyOptions>(Configuration);

// Configure MyOptions using codeservices.Configure<MyOptions>(myOptions =>{ myOptions.Option1 = "value1_from_action"; myOptions.Option2 = connectionStringConfig.GetConnectionString("DefaultConnection");});

public class HomeController : Controller

{

private readonly IOptions<MyOptions> _optionsAccessor;

public HomeController(IOptions<MyOptions> optionsAccessor)

{

_optionsAccessor = optionsAccessor;

}

// GET: /<controller>/

public IActionResult Index() => View(_optionsAccessor.Value);

}

public class MyOptions

{

public string Option1 { get;

set; }

public string Option2 { get;

set; }

}

Error Handling

Exception Handling Page

// Configure

if (env.IsDevelopment()) { app.UseDeveloperExceptionPage();} else { app.UseExceptionHandler("/Error");}

Status Code Pages// Configureapp.UseStatusCodePages();

app.UseStatusCodePages(context =>

context.HttpContext.Response.SendAsync("Handler, status code: " +

context.HttpContext.Response.StatusCode, "text/plain"));

app.UseStatusCodePages("text/plain", "Response, status code: {0}");

app.UseStatusCodePagesWithRedirects("~/errors/{0}");

app.UseStatusCodePagesWithReExecute("/errors/{0}");

ASP.NET MVC Handling

Exception filters

Model validation

Swagger

Swagger is a machine readable representation of a RESTful API

Swashbuckle is an open source project for generating Swagger documents for Web APIs

Set Up// Install package

Install-Package Swashbuckle -Pre

Add Swashbuckle to project.json: "Swashbuckle": "6.0.0-beta902"

// Configure

// Enable middleware to serve generated Swagger as a JSON endpoint

app.UseSwagger();

// Enable middleware to serve swagger-ui assets (HTML, JS, CSS etc.)

app.UseSwaggerUi();

// ConfigureServices

// Inject an implementation of ISwaggerProvider with defaulted settings applied

services.AddSwaggerGen();