This document provides an overview and introduction to ASP.NET 5 and MVC 6. It discusses the history of ASP.NET and outlines improvements in ASP.NET 5, including being cross-platform, modular, faster, and using NuGet packages. MVC 6 unifies MVC, Web API, and Web Pages and uses view components instead of child actions. Tag helpers generate markup and validation helpers are also introduced.
3. About Me
Senior Architect, Sela Group
Microsoft Regional Director, and an ASP.NET/IIS MVP
Co-author of courses and books
Focus on server, web, and cloud
Manager of the Israeli Web Developers User Group
4. History of ASP (18 years)
1996 - Active Server Pages (ASP)
2002 – ASP.NET
2008 – ASP.NET MVC
2010 – ASP.NET Web Pages
2012 – ASP.NET Web API, SignalR
2014 – ASP.NET vNext
5. Current ASP.NET stack
Windows Server
IIS
.NET Framework
ASP.NET
Web
Forms
MVC Web API
System.Web
HTTP
Modules
HTTP
Handlers
Request
Pipeline
Caching
Session
State
6. Problems with ASP.NET architecture
Limited hosting possibilities (IIS only)
Dependency on IIS environment (System.Web)
Web evolves faster than .NET framework
Requires full-blown .NET framework - resource
intensive and not web-friendly
Hard to optimize for lightweight high-
performance apps
7. Introducing ASP.NET 5 stack
OS
.NET CLR
ASP.NET
Web API MVC Web Pages
Host
IIS Self-hosted
.NET Core CLR
Middleware
11. Caution
At the time of this presentation, we are using
DNX-CLR-x86 1.0.0-beta4 (ASP.NET 5 beta 4)
As things are moving really fast in this new
world, it’s very likely that the things explained
here will slightly change
12. ASP.NET 5 – Agility
Faster Development Cycle
Features are shipped as packages
Framework ships as part of the application
More Control
Zero day security bugs patched by Microsoft
Same code runs in development and production
Developer opts into new versions, allowing breaking
changes
13. ASP.NET 5 - Fast
Runtime Performance
Faster startup times
Lower memory / higher density (> 90% reduction)
Modular, opt into just features needed
Use a raw socket, framework or both
Development productivity and low friction
Edit code and refresh browser
Flexibility of dynamic environment with the power of
.NET
Develop with Visual Studio, third party and cloud
editors
14. ASP.NET 5 – Cross Platform
Runtime
Windows, Mac, Linux
Editors
Visual Studio, Text, Cloud editors
OmniSharp – Sublime, Emacs, Vi, etc.
No editors (command line)
All Open Source with Contributions
15. ASP.NET 5 Features
New flexible and cross-platform runtime
New modular HTTP request pipeline
Robust environment configuration
Unified programming model for MVC API
See changes without re-building the project
Side-by-side versioning of the .NET Framework
Built in Dependency Injection
Ability to self-host or host on IIS
Open source in GitHub
16. File New Project Web
Web App
Class Lib?
Console App?
19. Let's talk about OWIN
Open Web Interface for .NET
Community project (http://owin.org)
Decouples application from server
Enforces modularity of the server
Stack of modules (middlewares) is processing
the request from application to server
Microsoft implementation of OWIN is "Katana"
21. ASP.NET 5 Middlewares
Improved HTTP performance
New HTTP request pipeline that is lean and fast
The new pipeline also supports OWIN
You choose what to use in your application
By registering middlewares
public void Configure(IApplicationBuilder app,
IHostingEnvironment env, ILoggerFactory loggerfactory)
{
app.UseErrorHandler("/Home/Error");
app.UseStaticFiles();
app.UseIdentity();
app.UseMvc(routes => ...)
}
22. Custom Middleware
Create middleware class
app.UseMiddleware<AppHeaderMiddleware>();
// Register before app.UseMvc(...);
public class AppHeaderMiddleware {
private readonly RequestDelegate next;
public AppHeaderMiddleware(RequestDelegate next) {
this.next = next;
}
public async Task Invoke(HttpContext context) {
context.Response.Headers.Append(
"X-Application", "ASP.NET 5 Sample App");
await this.next.Invoke(context);
}
}
Register in Startup.cs (IApplicationBuilder)
24. Package Management
ASP.NET 5 introduces a new, lightweight way to
manage dependencies in your projects
No more assembly references
Instead referencing NuGet packages
project.json file
25. Structure of the "project.json" file
Dependencies - lists all the dependencies of your
application (NuGet, source files, etc.)
Configuration - compilation settings (debug,
release)
Frameworks - target frameworks with their
dependencies
Sources - what should be compiled
Web root - server root of the app
Shared files - files shared with dependent projects
Commands - commands available to “dnx”
Scripts - pre/post events to hook scripts to
Metadata - general project information
28. Debugging without Roslyn
Change the
code
C#
Compiler
invoked
Load code
in memory
Execute
the dll
dll loaded
in memory
from File
system
Emits the
dll in file
system
29. Debugging with Roslyn
Change the
code
Load code
in memory
Code is
Executed in
memory
Roslyn
compiles
code in
memory
Time reduced from 7-8 second to 1-2 second
30. "K“ / ”DNX” Command Line Tools
KRE / DNX- Runtime Environment
Engine that runs your application (compilation system,
SDK tools, and the native CLR hosts)
KVM / DNVM - Version Manager
Tool for updating and installing different versions of
KRE/DNX
KPM / DNU- Package Manager
Tool to restore and install (NuGet) packages needed by
applications to run
K / DNX
Entry point to the runtime - starts the runtime with
commands
36. ASP.NET MVC 6
No more duplication - one set of concepts
Used for creating both UI and API
Smooth transition from Web Pages to MVC
Based on the new ASP.NET 5 pipeline
Built DI first
Runs on IIS or self-host
38. Routing Template Improvements
Inline constraints
Product/{ProductId:long}
Product/{ProductName:alpha}
Product/{ProductName:minlength(10)}
Product/{productId:regex(^d{4}$)}
Optional parameters
Product/{productId:long?}
Default values
Product/{productId:long=1}
Available with MapRoute() and [Route()]
https://github.com/aspnet/Routing/tree/dev/src/
Microsoft.AspNet.Routing
39. Where is the Web API
Configuration?
Route configuration -> attribute-based routing
Message handlers -> middleware pipeline
Filters and Formatters -> startup.cs
app.UseServices(services => {
services.Configure<MvcOptions>(options =>
{
options.AddXmlDataContractSerializerFormatter();
options.Filters.Add(new ValidatorFilterAttribute());
});
}
40. Controllers – Two Birds, One Stone
API – similar, but different
UI – same as with MVC 5
[Route("api/[controller]")]
public class ProductsController : Controller
{
[HttpGet("{id:int}")]
public Product GetProduct(int id)
{
return new Product() { ID = id };
}
}
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
41. Actions – API with IActionResult
[HttpGet("{id:int}", Name = "GetByIdRoute")]
public IActionResult GetById (int id)
{
var item = _items.FirstOrDefault(x => x.Id == id);
if (item == null) { return HttpNotFound(); }
return new ObjectResult(item);
}
[HttpPost]
public IActionResult CreateTodoItem([FromBody] TodoItem item)
{
_items.Add(item);
return CreatedAtRoute(
"GetByIdRoute", new { id = item.Id }, item);
}
42. IActionResult for UI and API
https://github.com/aspnet/Mvc/tree/dev/src/
Microsoft.AspNet.Mvc.Core/ActionResults
UI API
PartialViewResult BadRequestResult
RedirectResult ContentResult
ViewResult CreatedAtRouteResult
JsonResult HttpStatusCodeResult
JsonResult
ObjectResult
ChallengeResult
HttpNotFoundResult
FileContentResult
43. Content Negotiation
MVC still respects Accept headers
The XML formatter was removed from the MVC 6
pipeline
You can manually add it to the Formatters collection
Forcing a content-type:
Return a JsonResult
Use the [Produces("application/json")] attribute
Additional changes:
Actions returning string result in text/plain responses
Returning null/void – response will be HTTP 204 (no
content)
44. Last Controller Goodie - DI
Dependency Injection and MVC
ASP.NET 5 is DI-friendly
Basic DI container available throughout the stack
BYOC is also supported (already implemented for
Autofac, Ninject, StructureMap, Unity, and Windsor)
Out-of-the-box container supports
Singleton / Instance – single instance
Transient – new instance each time
Scoped – new instance per request
https://github.com/aspnet/DependencyInjection/tree
/dev/src
45. Last Controller Goodie - DI
public class ProductsController : Controller
{
private readonly IProductsRepository _repository;
public ProductsController(IProductsRepository repository)
{
this._repository = repository;
}
public IActionResult Index()
{
var products = _repository.GetAllProducts();
return View(products);
}
}
app.UseServices(services =>
{
services.AddTransient<IProductsRepository, DefaultProductsRepository>();
});
46. Look Ma No Controller
Use the Controller suffix
Inject HTTP request, principal, and view data with:
Convention-based property injection
Constructor injection
public class SimpleController
{
[Activate]
public ActionContext ActionContext { get; set; }
[Activate]
public ViewDataDictionary ViewData { get; set; }
[Activate]
public IUrlHelper Url { get; set; }
public string Get()
{
return "Hello world";
}
}
48. Child Actions in MVC <6
Rendering partial views with controller logic
and model
Do not confuse with Html.Partial
@Html.Action("GetProductDetails", "Products", new { id = 1})
[ChildActionOnly]
public ActionResult GetProductDetails(int id)
{
var product = _repository.GetProduct(id);
return PartialView("ProductDetails", product);
}
49. Child Actions in MVC 6
So what’s the problem?
Part of a controller, but invoked from a view
Controller flow must distinguish between HTTP calls and
view calls
Pattern lacks an asynchronous invocation
Solution?
Replace child actions with View Components
Same partial views, but declared in a separate class
Think of it as a “mini-controller”
Supports the same DI and POCO features as a controller
Implement actions as synchronous or asynchronous
50. View Components in MVC 6
//[ViewComponent(Name = "ProductDetails")]
public class ProductDetailsViewComponent : ViewComponent
{
private readonly IProductsRepository _repository;
public ProductDetailsViewComponent(IProductsRepository repository)
{
_repository = repository;
}
public IViewComponentResult Invoke(int id)
{
var product = _repository.GetProduct(id);
return View(product);
}
@Component.Invoke("ProductDetails", 1)
// Or as async, if InvokeAsync is implemented in the view component
@await Component.InvokeAsync("ProductDetails", 1)
51. And the Partial View?
Create a default.cshtml file
(content structured similar as with MVC <6)
Place file in:
Controller-specific:
Views/{controller}/Components/ProductDetails/Default.cshtml
Shared:
Views/Shared/Components/ProductDetails/Default.cshtml
Customizing view name is supported
Create a file other than Default.cshtml
Return View(viewName, model)
52. Injecting Services to Views
Preferable than using static classes/methods
Use interfaces instead of concrete types
Register in IoC using different lifecycles
public class CatalogService : ICatalogService
{
public async Task<int> GetTotalProducts() {...} // From ICatalogService
}
@inject MyApp.Services.ICatalogService Catalog
<html>
<body>
<h3>Number of products in the catalog</h3>
@await Catalog.GetTotalProducts()
</body>
</html>
services.AddTransient<ICatalogService, CatalogService>();
53. Last, but not Least, Tag Helpers
Do this:
Ah? What’s that?
Instead of doing this:
<form asp-anti-forgery="true" asp-action="UpdateProduct">
…
</form>
using (Html.BeginForm("UpdateProduct", "Products", FormMethod.Post))
{
@Html.AntiForgeryToken()
…
}
It’s the return of Web Controls, NOOOOOO!!!
54. Tag Helpers are not Evil
Tag Helpers generate markup only within their
enclosing tag
Less Razor/HTML mess in the .cshtml file
JavaScript directive style approach
Use C# to better construct the markup
Add/remove parts from the inner content
Generate complex HTML (recursive, nested, …)
Cache the output
55. Existing Tag Helpers
HTML elements
<a>, <form>, <input>, <label>, <link>, <script>,
<select>, <textarea>
Logical
<cache>
Placeholders
ValidationSummary (<div>), ValidationMessage (<span>)
You can create your own Tag Helpers
Check out the source for reference
https://github.com/aspnet/Mvc/tree/dev/src/Micros
oft.AspNet.Mvc.TagHelpers
56. Key Improvements in ASP.NET 5
Totally modular
NuGet is first-class citizen in ASP.NET 5
Everything is a package
Lightweight - you use minumum set of modules
Faster startup, lower memory (>90%)
Does not require .NET Framework installation -
runtime environment (CLR) can be deployed
with your application
57. Key Improvements in ASP.NET 5
Cross platform - can be hosted anywhere:
IIS, self-hosted, Linux, MAC...
Web Forms are left aside for now
Better developer experience
No-compile debugging with Roslyn, MVC unified
programming model, basic DI out-of-the-box...
Everything is open-source
Architecture is OWIN based
58. Getting Started with ASP.NET 5
Ships with Visual Studio 2015
Walkthroughs and samples at http://asp.net/vnext
Documentation at http://docs.asp.net/en/latest
Get the code from http://github.com/aspnet
Read blogs at http://blogs.msdn.com/b/webdev
Try out a nightly build from MyGet
https://www.myget.org/F/aspnetvnext
My Info
idof@sela.co.il
@idoFlatow
http://bit.ly/flatowblog
Editor's Notes
Other dependencies that people may find relevant: aspnet.diagnostics, server.weblistener
Don’t use void with beta3, it ignores status codes set in the method