44
Philip Japikse (@skimedic) [email protected] www.skimedic.com/blog Microsoft MVP, ASPInsider, MCSD, MCDBA, CSM, CSP Principal Consultant/Architect, Strategic Data Systems ASP.NET MVC6

User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

Page 1: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

Philip Japikse (@skimedic)

[email protected]

www.skimedic.com/blog

Microsoft MVP, ASPInsider, MCSD, MCDBA, CSM, CSP

Principal Consultant/Architect, Strategic Data Systems

ASP.NET MVC6

Page 2: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

Principal Consultant/Architect, Strategic Data Systems

http://www.sds-consulting.com

Developer, Coach, Author, Teacher

http://bit.ly/pro_csharp

Microsoft MVP, ASPInsider, MCSD, MCDBA, CSM, CSP

Founder, Agile Conferences, Inc.

http://www.dayofagile.org

President, Cincinnati .NET User’s Group

Phil.About()

Page 3: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

.NET CORE 1

Page 4: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

Open source, cross platform

development platform for:

Windows, macOS, Linux

Can be ported to other platforms

Compatible with

.NET f/w, Xamarin, Mono

Full Command line support

Consists of (to name a few):

.NET Core – console

Entity Framework Core

ASP.NET Core

Windows 10 Universal Windows

Platform (UWP)

Xamarin.Forms

WHAT IS .NET CORE?

Page 5: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

ASP.NET CORE MVC 6

Page 6: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

Based on .NET Core

No longer dependent on

System.Web.dll or IIS

Cross Platform

Side by Side versioning

MVC and Web API Unified into the

same framework

Built on

Dependency Injection

Environment based configuration

Default pipeline == NOTHING!

Fully customizable for your

application needs

ASP.NET AND WEB API COMPLETELY RETOOLED

Page 7: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

Configuration and pipeline

management no longer use:

global.asax, web.config, app_start

Instead uses json and startup.cs

Routing

Attribute Routing is 1st class citizens

Route table still supported and used

Changes from RCx:

Dropped gulp/npm

Added BundlerMinifier

JSON is camelCased (instead of

PascalCased)

CHANGES FROM PREVIOUS VERSIONS

Page 8: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

BUNDLING AND MINIFICATION

Page 9: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

BUNDLING AND MINIFICATION

RTM templates no longer use gulp/grunt for B&M

Added Mads Kristensen’s BundlerMinifier

https://github.com/madskristensen/BundlerMinifier/wiki

Configure bundles with bundleconfig.json

Execute via calling ‘dotnet bundle [clean] [watch] [help]’

Command line || project.json

Page 10: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

PROJECT JSON

Page 11: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

PROJECT.JSON

Currently holds configuration information

Going away in a future version

Base settings:

{"version": "1.0.0-*","dependencies": {

"Microsoft.NETCore.App": {"type": "platform", "version": "1.0.0" },"NETStandard.Library": "1.6.0","System.Linq.Queryable": "4.0.1"},"frameworks": {"netcoreapp1.0": {"imports": ["dnxcore50"]}

},}

Page 12: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

ADDING PROJECT DEPENDENCIES

Specify project as target (instead of package) to indicate local project

{"dependencies": {

“MVC6Demo.Models": {"target": "project","version": "1.0.0-*"

}},

}

Page 13: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

ANATOMY OF AN MVC6 APP

A console app that creates a web server in Main

launchSettings.json configures IIS

var host = new WebHostBuilder().UseKestrel().UseUrls("http://*:40001/").UseContentRoot(Directory.GetCurrentDirectory()).UseIISIntegration().UseStartup<Startup>().Build();

host.Run();

Page 14: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

THE STARTUP CLASS

Page 15: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

GETTING CONFIGURATION INFORMATION

Configuration uses json files and the Configuration Builder class

public Startup(IHostingEnvironment env){

_env = env;var builder = new ConfigurationBuilder()

.SetBasePath(env.ContentRootPath)

.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)

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

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

}

Page 16: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CUSTOM CONFIGURATION SECTIONS

Add data to json

Use ConfigurationBuilder to get information (usually in Startup)

var customSection = Configuration?.GetSection("CustomSettings");Var address = customSection?.GetSection("ServiceAddress")?.Value;

{"Logging": ...,"CustomSettings": {"ServiceAddress": "http://localhost:40002/","ImageLocation": "~/images/"

}}

Page 17: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CONFIGURING THE PIPELINE

The Configure method sets up how to respond to HTTP requests

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

{app.UseExceptionHandler("/Home/Error");app.UseStaticFiles();app.UseMvc(routes =>{

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

});}

Page 18: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CONDITIONAL PIPELINE CONFIGURATION

Use environment options for conditional pipeline configuration

public void Configure(IApplicationBuilder app, IHostingEnvironment env,ILoggerFactory loggerFactory)

{if (env.IsDevelopment()){

app.UseDeveloperExceptionPage();app.UseBrowserLink();

}else{

app.UseExceptionHandler("/Home/Error");}

}

Page 19: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CONFIGURING FRAMEWORK SERVICES

Used to configure any services needed by the application

public void ConfigureServices(IServiceCollection services){

// Add framework services.services.AddMvc(config =>{

config.Filters.Add(new SimpleAuthenticationActionFilter());}).AddJsonOptions(options =>{ //Revert to PascalCasing for JSON handling

options.SerializerSettings.ContractResolver = new DefaultContractResolver();});//Additional services for DI added here (covered later in this presentation)

}

Page 20: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

DEPENDENCY INJECTION

Page 21: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CONFIGURING DI SERVICES

Configured in Startup.cs

Used to configure any services needed by the application

Transient – created each time they are requested

Scoped – created once per request

Singleton – created once (use this instead of implementing singleton dp

public void ConfigureServices(IServiceCollection services){

services.AddSingleton<ICustomSettings>(new CustomSettings(Configuration));services.AddSingleton<IWebApiCalls, WebApiCalls>();

}

Page 22: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

INJECTING SERVICES INTO CONTROLLERS AND VIEWS

Dependencies are configured in Startup.cs

Instances are pulled into classes automagically

FromServices attribute is optional

Instances are pulled into views with the @inject directive

public ShoppingCartController([FromServices]IShoppingCartRepo repo){ //Omitted for brevity }

public void ConfigureServices(IServiceCollection services){

//https://docs.asp.net/en/latest/fundamentals/dependency-injection.htmlservices.AddScoped<IShoppingCartRepo, ShoppingCartRepo>();

}

@inject <type> <name>@inject IWebApiCalls apiCalls

Page 23: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

ROUTING

Page 24: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

ROUTING

Route table used for default route

Controller and actions can define specific routes

[Route("api/[controller]/{customerId}")]public class ShoppingCartController : Controller{

[HttpGet("{Id?}")]public async Task<IActionResult> AddToCart(

int Id, int customerId, string returnUrl, int quantity = 1){

//Code omitted}

}

Page 25: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

VIEW COMPONENTS

Page 26: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

VIEW COMPONENTS

Combine child actions and partial views

Composed of a class and a return value (typically a view)

Are not reacheable as an endpoint

Do not use model binding or filters

public class Menu : ViewComponent{

public async Task<IViewComponentResult> InvokeAsync(){

var cats = await WebAPICalls.GetCategories();if (cats != null) {return View("MenuView", cats);}return new ContentViewComponentResult(errorMessage);

}}

Page 27: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

INVOKING VIEW COMPONENTS

Typically called from a view

Can be called from an action

Views *must* be located in:

Views/<controller_name>/Components/<view_component_name>/<view_name>

Views/Shared/Components/<view_component_name>/<view_name>

View/Shared/Components/Menu/MenuView

Are named “Default.cshtml”

Can be changed

@await Component.InvokeAsync(nameof(Menu) [, new {parameters}])[email protected](nameof(Menu) [, new {parameters}])

Page 28: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

TAG HELPERS

Page 29: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

TAG HELPERS

Server side code that create markup in (and for) HTML tags

Similar to @Html helpers

Scope is limited to containing tag

Tag helpers are much simpler and cleaner to use

Not all @Html.Helpers have corresponding tag helpers

You can create custom tag helpers

@Html.Label("FirstName", "First Name", new {@class="caption"})

<label class=“caption“ asp-for=“FirstName“></label>Generates:<label class="caption" for="FirstName">First Name</label>

Page 30: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CONTROLLING TAG HELPER SCOPE

Controll scope with @addTagHelper, @removeTagHelper

@addTagHelper || @removeTagHelper <tagnames>,assemblyName

Can opt out with !

Use @tagHelperPrefix to force opt in

(included in _ViewImports.cshtml)@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers@addTagHelper *, MVC6Demo

<!label asp-for=“FirstName”>First Name</!label>

<th:label asp-for=“FirstName”>First Name</th:label>

Page 31: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

BUILT IN TAG HELPERS

Form

Generates antiforgery token, provides options for route and route

parameters

Adds in antiforgery token

Similar to Html.BeginForm and Html.BeginRouteForm helpers

<form asp-action="Edit" asp-area="" asp-controller="Product" asp-route="Edit" asp-route-id="@Model.Id">

Page 32: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

BUILT IN TAG HELPERS

Input

Adds id and name attributes based on the model expression

Determines input type based on the .NET type

Generates data-val annotations based on validation attributes

Html.TextBox[For], Html.Editor[For]

TextArea

Adds id and name attributes based on the model expression

<input type="hidden" asp-for="Id" />

<textarea asp-for="Description"></textarea>

Page 33: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

BUILT IN TAG HELPERS

Label

Uses the Display Attribute to set content

Validation

For entire model or properties

Similar to Html.ValidationMessageFor and Html.ValidationSummaryFor helpers

Select

Generates the select and option tags

<label asp-for="CurrentPrice"></label>

<div asp-validation-summary="ModelOnly" class="text-danger"></div><span asp-validation-for="CurrentPrice" class="text-danger" />

<select asp-for=“Country" asp-items="Model.Countries"></select>

Page 34: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CUSTOM TAG HELPERS

Derive from TagHelper

Public properties become lower-case-kebab attributes

Process[Async] creates the output

public class EmailTagHelper : TagHelper{

// Can be passed via <email mail-to="..." />. // Pascal case gets translated into lower-kebab-case.public string MailTo { get; set; }public string EmailDomain { get; set; } = "outlook.com";public override void Process(TagHelperContext context, TagHelperOutput output){

output.TagName = "a"; // Replaces <email> with <a> tagvar address = MailTo + "@" + EmailDomain;output.Attributes.SetAttribute("href", "mailto:" + address);output.Content.SetContent(address);

}}

Page 35: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CUSTOM VALIDATIONS

Page 36: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CUSTOM VALIDATION

MVC6 supports server and client side custom validation

Derive from ValidationAttribute and IClientModelValidator

public class MustNotBeGreaterThanAttribute : ValidationAttribute, IClientModelValidator

{protected override ValidationResult IsValid(

object value, ValidationContext validationContext) { //Code }

public void AddValidation(ClientModelValidationContext context) { //Code }}

Page 37: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CUSTOM VALIDATION – SERVER SIDE

ValidationResult IsValid is used for server side validations

ValidationContext exposes additional information about the model (if

necessary)

public class MustBeGreaterThanZeroAttribute : ValidationAttribute, IClientModelValidator

{protected override ValidationResult IsValid(

object value, ValidationContext validationContext){

MyViewModel obj = (MyViewModel) validationContext.ObjectInstance;var otherPropertyInfo =

validationContext.ObjectType.GetProperty(_otherPropertyName);//If successfulreturn ValidationResult.Success;//If errorreturn new ValidationResult(ErrorMessageString);

}}

Page 38: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

CUSTOM VALIDATION – CLIENT SIDE

Must include jquery.validate and jquery.validate.unobtrusive

Add IClientModelValidator Validation adds the data-val attributes to element

Custom JavaScript is used for client side validations

public void AddValidation(ClientModelValidationContext context){

context.Attributes.Add("data-val-greaterthanzero", errorMessage);}

$.validator.addMethod("greaterthanzero", function (value, element, params) {return value > 0;

});

$.validator.unobtrusive.adapters.add("greaterthanzero", function (options) {options.rules["greaterthanzero"] = true;options.messages["greaterthanzero"] = options.message;

});

Page 39: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

FILTERS

Page 40: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

FILTERS

Filters in ASP.NET MVC allow you to run code before or after a particular

stage in the execution pipeline.

Filters can be configured globally, per-controller, or per-action.

Many types available

Action

Exception

Authorization

Resource

Result

Page 41: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

EXCEPTION FILTERS

Come into play on unhandled exceptions

Configured with MVC (for whole application filters)

public class SpyStoreExceptionFilter : IExceptionFilter{

public void OnException(ExceptionContext context){

var ex = context.Exception;var response = new ErrorMessage {Message = ex.Message };context.Result = new ObjectResult(response) {StatusCode = 500};

}}

services.AddMvc(config => config.Filters.Add(new SpyStoreExceptionFilter(_env.IsDevelopment())).Filters.Add(new SimpleAuthenticationFilter()));

Page 42: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

ACTION FILTERS

Come into play before and/or after actions are executedpublic class SimpleAuthenticationActionFilter : IActionFilter{

public void OnActionExecuting(ActionExecutingContext context){ // do something before the action executes}public void OnActionExecuted(ActionExecutedContext context){ // do something after the action executes}

}

Page 43: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

Questions?

Page 44: User Story Mapping · TAG HELPERS Server side code that create markup in (and for) HTML tags Similar to @Html helpers Scope is limited to containing tag Tag helpers are much simpler

[email protected]

www.sds-consulting.com

[email protected]

www.skimedic.com/blog

www.twitter.com/skimedic

www.hallwayconversations.com

www.about.me/skimedic

Contact Me

Find the code at: https://github.com/skimedic/DotNetCore