ASP.NET Core 1.0

Click here to load reader

  • date post

  • Category


  • view

  • download


Embed Size (px)

Transcript of ASP.NET Core 1.0

PowerPoint Presentation

ASP.NET Core: Reimagining Web Application Development in .NETIdo FlatowSenior ArchitectMicrosoft MVP & RD Sela [email protected]


AgendaASP.NET HistoryASP.NET Core 1.0 and .NETASP.NET Core 1.0 FeaturesASP.NET Core MVC

ASP.NET, then and now

History of ASP (20 years)1996 - Active Server Pages (ASP) 2002 ASP.NET2005 ASP.NET 22008 ASP.NET MVC2012 ASP.NET Web API2014 ASP.NET vNext2015 ASP.NET 5 RC12016 ASP.NET Core 1.0 (June 27th, 2016)

Problems with ASP.NET ArchitectureLimited hosting possibilities (IIS only)Dependency on IIS environment (System.Web)Web evolves faster than the .NET FrameworkRequires full-blown .NET Framework Resource intensive and not web-friendlyHard to optimize for lightweight high-performance appsNot completely cloud-optimized


Introducing ASP.NET Core 1.0(Tools in Preview 2)OS


ASP.NETMVC(UI + API)HostSelf-HostedIIS.NET Core CLRMiddleware


What is Tooling?Everything that is part of the frameworkCommand line tools dotnet CLIProject toolsASP.NET templatesxproj / csprojVisual Studio toolsConfiguration IntelliSenseDebugger support

Two Runtimes.NET Full Framework (4.6)Not going away Windows hosting with full .NET APIs.NET Core 1.0Subset of the full frameworkNo Windows Forms, WPF, SilverlightNo System.Web (WebForms)Implemented as set of NuGet packagesCross-platform and Nano server support

Getting to know ASP.NET Core

ASP.NET Core FeaturesFlexible and cross-platform runtimeModular HTTP request pipelineUnifying MVC, Web API, and Web PagesSide-by-side versioning with .NET CoreBuilt-in Dependency InjectionSelf-host and IIS-hosted (sort of)Open source on GitHub

Creating a new ASP.NET Core projectDemo

Solution and Projectsglobal.jsonProject references (in addition to the .sln)wwwrootRoot for static content (html, css, js, images, etc)Program.csASP.NET hosting libraries. This is where it all startsproject.jsonReferences, compiler settings, tooling (replaces web.config and packages.config)Startup.csDI and pipeline configuration (replaces global.asax and configuration code)




project.json, startup.cs and Program.csDemo

ASP.NET Core MiddlewaresImproved HTTP performanceNew lean and fast HTTP request pipelineYou choose what to use in your applicationBy registering middlewarespublic void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerfactory){ app.UseExceptionHandler("/Home/Error"); app.UseStaticFiles(); app.UseIdentity(); app.UseMvc(routes => ...)}

Wheres the AppSettings?Not relying on web.config anymoreNew configuration system based on key/value pairs:JSON filesINI filesXML filesEnvironment variablesConfiguration can come from multiple resourcesLast resource wins

Loading Settingsvar builder = new ConfigurationBuilder() .SetBasePath(env.ContentRootPath) .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddXmlFile("appsettings.xml", optional:true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json",true);

if (env.IsDevelopment()){ builder.AddUserSecrets();}

builder.AddEnvironmentVariables();IConfigurationRoot Configuration = builder.Build();...

string connString = Configuration["Data:Default:ConnectionString"];

($"appsettings.{env.EnvironmentName}.jsonThe $ is C# 6 string interpolation17

Dependency InjectionASP.NET Core is DI-friendlyBasic DI container available throughout the stackBYOC is also supported (already implemented for Autofac, Dryloc, StructureMap, etc.)Out-of-the-box container supports:Singleton / Instance single instanceTransient new instance each timeScoped new instance per request (HTTP context)

DI with Controllerspublic class ProductsController : Controller{ private readonly IProductsRepository _repository; public ProductsController(IProductsRepository repository) { this._repository = repository; }

public IActionResult Index() { var products = _repository.GetAllProducts(); return View(products); }}services.AddTransient();

LoggingASP.NET Core has built-in support for loggingUses the built-in DI to get a logger instanceStandard logger outputs: category, log level, event Id, and messageBuilt-in loggers for:Console (hosting from cmd/terminal)TraceSource (good old System.Diagnostics)Debug (Visual Studio output window)Custom loggers are also available (log4net, serilog, elmah, etc.)

Logging with Controllerspublic class TodoController : Controller{ private readonly ITodoRepository _todoRepository; private readonly ILogger _logger; private const int LIST_ITEMS = 1001;

public TodoController(ITodoRepository todoRepo, ILogger logger) { _todoRepository = todoRepo; _logger = logger; }

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

The dotnet CLICross-platform command line toolchainWritten in .NET Core

External commands dotnet newdotnet restoredotnet build --output /stuffdotnet /stuff/new.dlldotnet publishdotnet efdotnet razor-toolingDotnet aspnet-codegenerator


Hosting ASP.NET CoreASP.NET Core 1.0 is a stand-alone applicationUses Kestrel HTTP server (based on libuv, as with node.js)Self-hosting with .NET CoreCompiled into a .dll file, hosted by the dotnet CLISelf-hosting with .NET 4.6Compiles into an .exe fileKestrel or the WebListener server (Windows HTTP.sys)IIS-hosted (.NET Core / .NET 4.6)IIS uses the ASP.NET Core Module to start the self-hosted appASP.NET Core template generates the required web.configStarts either dotnet webapp1.dll or webapp.exe

Cross-platform ASP.NET Core



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

Other dependencies that people may find relevant: aspnet.diagnostics, server.weblistener 29

Web API ConfigurationRoute configuration -> attribute-based routing Message handlers -> middleware pipelineFilters and Formatters -> startup.cs

services.AddMvc() .AddXmlDataContractSerializerFormatters() .AddMvcOptions(options => { options.Filters.Add(new ValidatorFilterAttribute()); }) .AddJsonOptions(jsonOptions => { jsonOptions.SerializerSettings.Formatting = Formatting.Indented; });

For XML, add a nuget to the project.json:"Microsoft.AspNet.Mvc.Formatters.Xml": "6.0.0-rc1-final",


Controllers Two in OneUI same as with MVC 5

API similar, but different

public class HomeController : Controller{ public IActionResult Index() { return View(); }}[Route("api/[controller]")]public class ProductsController : Controller{ [HttpGet("{id:int}")] public Product GetProduct(int id) { return new Product() { ID = id }; }}

Other dependencies that people may find relevant: aspnet.diagnostics, server.weblistener 31

Actions IActionResult[HttpGet("{id:int}", Name = "GetByIdRoute")]public IActionResult GetById (int id){ var item = _items.FirstOrDefault(x => x.Id == id); if (item == null) { return NotFound(); }

return new ObjectResult(item);}

[HttpPost]public IActionResult CreateTodoItem([FromBody] TodoItem item){ _items.Add(item);

return CreatedAtRoute( "GetByIdRoute", new { id = item.Id }, item);}

Dont use void with beta3, it ignores status codes set in the method32

Content NegotiationMVC still respects Accept headersXML formatter was removed from the MVC pipelineYou can manually add it to the Formatters collectionwith AddXmlDataContractSerializerFormattersForcing a content-type:Return a JsonResultUse the [Produces("application/json")] attributeAdditional changes:Actions returning string result in text/plain responsesReturning null response will be HTTP 204 (no content)

Null returns 204, but void return 200 empty


Showing Some UI for Your APISwagger - a JSON-based service description frameworkCreate a Swagger endpoint using Swashbuckle.SwaggerGenBrowse to /swagger/v1/swagger.jsonHost a built-in UI for testing APIs with Swashbuckle.SwaggerUiBrowse to /swagger/ui"dependencies": { "Swashbuckle.SwaggerGen": "6.0.0-beta901", "Swashbuckle.SwaggerUi": "6.0.0-beta901"}services.AddSwaggerGen();app.UseSwagger();app.UseSwaggerUi();

Enough with controllers,What about views?

Oh, right!

Injecting Services to ViewsPreferable than using static classes/methodsUse interfaces instead of concrete typesRegister in IoC using different lifecyclespublic class CatalogService : ICatalogService {public async Task GetTotalProducts() {...} // From ICatalogService}@inject MyApp.Services.ICatalogService Catalog

Number of products in the [email protected] Catalog.GetTotalProducts()


Flushing Content with RazorIn ASP.NET