SLICE YOUR DEVELOPMENT TIME WITH VISUAL STUDIO… · slice your development time with visual...

74
Philip Japikse (@skimedic) [email protected] www.skimedic.com/blog Microsoft MVP, ASPInsider, MCSD, MCDBA, CSM, CSP SLICE YOUR DEVELOPMENT TIME WITH VISUAL STUDIO, ASP.NET MVC, AND RAZOR

Transcript of SLICE YOUR DEVELOPMENT TIME WITH VISUAL STUDIO… · slice your development time with visual...

Philip Japikse (@skimedic)

[email protected]

www.skimedic.com/blog

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

SLICE YOUR DEVELOPMENT TIME WITH VISUAL STUDIO,

ASP.NET MVC, AND RAZOR

PHIL.TOSTRING()

2

• Developer, Author, Teacher

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

• Founder, Agile Conferences, Inc.

• President, Cincinnati .NET User’s Group

• Co-host, Hallway Conversations

• www.hallwayconversations.com

STARTER SITES AND TEMPLATES

3

• Intranet –

• Forms authentication

• Internet –

• Windows authentication

• Mobile –

• Optimized for Mobile Devices

• WebAPI

• Single Page Application

• Facebook Application

ASP.NET MVC STARTER PROJECTS (MVC4)

4

MVC EMBRACES OPEN SOURCE

5

• jQuery

• jQuery-ui

• jQuery.mobile

• jQuery.unobtrusive-ajax

• jQuery.validate

• knockout

• modernizr

STARTER SITES

6

@media only screen and (max-width: 850px) {.. }

NOTE: @media is a CSS3 element rendered by the browser, not a MVC4 specific item

ADAPTIVE RENDERING MEDIA QUERIES

7

ONE ASP.NET

8

SINGLE TEMPLATE

9

ONE HAPPY FAMILY

10

INSTEAD OF SEPARATE TEMPLATES

11

THE NEW UI

12

MOBILE

13

VIEWPORT META TAG

14

<meta name="viewport" content="width=device-width" />

VIEW SWITCHING

15

ADD JQUERY MVC TO INTERNET APPS

16

• (NuGet) Install-Package jQuery.Mobile.MVC

• Adds:

• _Layout.Mobile.cshtml

• _ViewSwitcher.cshtml

• ViewSwitcherController.cs

VIEW SWITCHING

17

DISPLAY MODES

18

CREATING DISPLAY MODES

19

DisplayModeProvider.Instance

.Modes.Insert(0,

new DefaultDisplayMode("iPhone") {

ContextCondition =

(context =>

context.GetOverriddenUserAgent() .IndexOf("iPhone",

StringComparison.OrdinalIgnoreCase) >= 0) });

VISUAL STUDIO & MVC

VISUAL STUDIO MVC GOODIES

21

• Creating Custom Projects

• Testing is First Class Citizen

• Extendable for preferred test f/w

• Creating Project Extensions

• Creating Custom Views

• Controller and View scaffolding

ADDING CUSTOM TEST PROJECT (2010/2012)

22

MSTEST IS DEFAULT TEST F/W

23

• Many want to use other f/w

• May use different Test Project types in solution

• .NET: NUnit, MbUnit, etc

• JavaScript/HTML: QUnit, Jasmine, JSSpec, etc.

• Setting up all dependencies takes time

• Manually configuring test projects doesn’t provide

business value

CREATE MVC TEST PROJECT TEMPLATE

24

• Create Project Template

• File -> Export Template…

• Copy to

•%VSInstall%Common7\IDE\Project\Templates\

Csharp\Test

• Run “devenv /installvstemplates”

CREATING A PROJECT TEMPLATE

25

USE THE NEW TEMPLATE

26

ADD TO THE MVC WIZARD

27

• Add registry entries

• Run “devenv /setup”

REGISTERING TEST PROJECTS (2010)

28

HKLM\Software\Microsoft Visual Studio\10.0\MVC4\TestProjectTemplates\

[Name]\[Language]

REGISTERING TEST PROJECTS (2012)

29

HKLM\Software\Wow6432Node\Microsoft\VisualStudio\11.0\MVC4\

TestProjectTemplates\[Name]\[Language]

UPDATED TEST PROJECT OPTIONS

30

CREATE VSIX PACKAGE

31

WHY VSIX?

32

• Distribution

•Nuget

•Gallery

• Sneaker Net

• Click to install

CREATE A VSIX PACKAGE

33

• Create Project Template

• Create Empty VSIX Project

• Must have VS 2012 SDK installed

• Add Project Template to VSIX

• Build

• Deploy

• (No, it’s not really THAT simple)

• http://bit.ly/YKDNBB

CUSTOM VIEWS

34

CUSTOM VIEW TEMPLATES

35

• System

• %VSInstall%\Common7\IDE\ItemTemplates\CSharp\Web\MVC

3\CodeTemplates\AddView\CSHTML

• Project

• Portable through Source Control

• Create Folder CodeTemplates\AddView\CSHTML

• Add T4 Template Files

• Clear “Custom Tool” field => Build Project

CUSTOM SCAFFOLDING

36

ADD MVCSCAFFOLDING FROM NUGET

37

SCAFFOLD YOUR MODEL

38

• PM> Scaffold Controller <table> -Repository –Force

• Creates:

•Controller

•Views

•Context

• IRepository

CUSTOMIZE THE SCRIPTS & TEMPLATES

39

• Modify the default PowerShell scripts or T4 templates

• <solutiondir>\packages\MvcScaffolding.1.0.9\tools

• Override the defaults

• PM> Scaffold CustomTemplate scaffoldername

templatename

• Create New scaffolder

• PM> Scaffold CustomScaffolder scaffoldername

FOR MORE INFORMATION:

40

• The Project Home:

• http://mvcscaffolding.codeplex.com/

• NuGet

• http://nuget.org/packages/MvcScaffolding/

• Steve Sanderson’s Blog series

• http://bit.ly/hwNUNS

SIDE WAFFLE/TEMPLATE BUILDER

3/18/2015 41

SIDEWAFFLE/TEMPLATE BUILDER

• The new way to create and share templates

• Project and Item templates

• http://sidewaffle.com/

• Visual Studio Gallery: http://bit.ly/1rUpEE6

• Use the template pack from NuGet

• OR

• Create your own

3/18/2015 42

SIDEWAFFLE TEMPLATES

3/18/2015 43

PROJECT TEMPLATES WITH TEMPLATE BUILDER

3/18/2015 44

• Create project template (as shown before)

• Create a new VSIX package project

• Add templatebuilder

• Install-package TemplateBuilder -pre

• Add your project to the solution

• Blah blah blah

• Tada! A new template pack

RESOURCES

3/18/2015 45

• Video: Creating a Visual Studio Project Template http://bit.ly/10KOL3a

• Article: Creating multi-project templates :http://bit.ly/1vKYlh2

• WIKI: https://github.com/ligershark/side-waffle/wiki

RAZOR

RAZOR VIEW ENGINE

47

• Razor views don’t extend System.Web.Page

• No more Page directive

• Easier to test

• Cleaner Embedding of Server Side Code

• Supports everything you’d expect from WebFormsViewEngine

@{

//Code Block

var foo = "Foo";

var bar = "Bar";

var htmlString =

"<ul><li>one</li><li>two</li></ul>";

}

@foo<br />

@htmlString<br />

@foo.@bar<br />

@Html.Raw(htmlString)

<%

//Code Block

var foo = "Foo";

var bar = "Bar";

var htmlString = "<ul><li>one</li><li>two</li></ul>";

%>

<%= foo %><br />

<%: htmlString%><br />

<%=foo %>.<%=bar%><br />

<%=htmlString %>

LESS TYPING, EASIER TO READ

48

Hello, @world.

-------------------------------

@for (int i = 0; i <5; i++)

{

@:Straight Text

<div>Value:@i</div>

<text>

Lines without HTML tag

</text>

<br/>

}

-------------------------------

<a href=“/Products/Detail/@p.ProductID”>

@p.ProductName</a>

Hello, <%= world %>.

-------------------------------

<% for (int i = 0; i < 5; i++)

{

%>

Straight Text

<div>Value:<%=i%></div>

Lines Without HTML tag

<br />

<% } %>

-------------------------------

< href=“/Products/Detail/<%=p.ProductID%>”><%= p.ProductName</a>

LESS TYPING, EASIER TO READ

49

SMART @ HANDLING

50

@{ var foo = “Foo”; }

@*

Multiline Comments

Hi.

*@

Email Address Handling:

[email protected] = [email protected]

test@foo = test@foo

test@(foo) = testFoo

PROBLEM AREAS

3/18/2015 51

• Generics:

• var item = GetOrderItem<string>(order);

• Must be:

• var item = ( GetOrderItem<string>(order) );

• Too many “.”:

• “/orders/products/@Product.Name.jpg

• Must be

• “/orders/products/(@Product.Name).jpg

CLEANER VIEWS

3/18/2015 52

return View();

---------------------------------------------------

@{ //Layout =

"~/Views/Shared/_BlankLayout.cshtml";

ViewBag.Title = "Home Page"; }

<h2>@ViewBag.Message</h2><p>

Content Goes Here</p>

return PartialView()

---------------------------------------------------

<h2>@ViewBag.Message</h2><p>

Content Goes Here

</p>

RAZOR VIEWS

53

DISPLAY AND EDITOR TEMPLATES

54

CREATING TEMPLATES

55

• Default templates:

• <TypeName>.cshtml (e.g. Boolean.cshtml)

• Add to DisplayTemplates/EditorTemplates folder

• Under Shared for all

• Named Templates

• @Html.DisplayFor(x=>x.foo,”Template”)

• @Html.EditorFor(x=>x.foo,”Template”)

DISPLAY TEMPLATE

56

@Html.DisplayFor(model => model.[boolean])

-----------------------------------------------------------------

@model bool?

@{

if (ViewData.ModelMetadata.IsNullableValueType)

{

if (!Model.HasValue) { @:Unknown }

else if (Model.Value) { @:Yes }

else { @:No }

} else {

if ((bool)Model) { @:Yes }

else { @:No }

}

}

EDITOR TEMPLATE

57

@Html.EditorFor(model => model.[boolean] )

-----------------------------------------------------------------

@model System.Boolean?

@{

var list = new List<SelectListItem>();

if (ViewData.ModelMetadata.IsNullableValueType)

{ list.Add(new SelectListItem { Text = "", Value = ""}); }

list.Add(new SelectListItem { Text = "Yes", Value = "true" });

list.Add(new SelectListItem {Text = "No", Value = "false" });

}

@(Html.Telerik()

.DropDownListFor(m => m)

.Name(ViewData.TemplateInfo.GetFullHtmlFieldName(string.Empty))

.BindTo(list)

)

DELEGATES, FUNCTIONS, AND HELPERS

58

ENCAPSULATING WORK

59

• Functions vs Helpers

• Functions are used for non-UI code

• Helpers render markup

• Locations:

• Inline

• App_Code

• Extension Methods

FUNCTIONS (NON-UI CODE)

60

@functions {

public [static] IList<string> SortList(IList<string> strings) {

var list = from s in strings orderby s select s;

return list.ToList();

}

}

--------------------------------------------------------------

@{ var myList = new List<string> {"C", "A", "Z", "F"};

var sortedList = SortList(myList); //MyFunctions.SortList(myList)

}

@foreach (string s in sortedList) {

@s&nbsp;

}

HELPERS (UI CODE)

61

@helper ShowDiscountedPrice(Customer cust, Decimal price)

{

if (cust.IsPreferred) {

@String.Format(“{0:C2}”,price * .9)

} else {

@String.Format(“{0:C2}”,price)

}

}

RAZOR DELEGATES

62

@{

Func<dynamic, object>

b = @<strong>@item</strong>;

}

This will be bold: @b("Foo")

EXTENDING @HTML

63

@Html.LabelWithRequiredFor(m => m.UserName)

------------------------------------------------------------------------

public static class LabelHelper

{

public static MvcHtmlString LabelWithRequiredFor<TModel, TValue>(

this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)

{

//Code to create the HTML Label

//Uses Data Annotations

return MvcHtmlString.Create(label.ToString());

}

}

CHANGING THE BASE PAGE

3/18/2015 64

STEPS TO CREATE A NEW BASE PAGE

3/18/2015 65

• Inherit from WebViewPage

• Add dynamic inheritor

• Have at it!

CREATING A BASE PAGE

3/18/2015 66

public class CustomBasePage<TModel>:WebViewPage<TModel> {

public override void Execute() {

throw new NotImplementedException(); }

protected MyLabelHelper MyHelper{

get { return new MyLabelHelper(); } }

}

public abstract class CustomBasePage : CustomBasePage<dynamic> {

}

USING THE BASE PAGE

3/18/2015 67

@inherits PhotoGallery.BasePageExample.CustomBasePage

<PhotoGallery.Models.Customer>

@MyHelper.AddElipseIfTooLong("FooBar",3);

DISPLAY MODES ISSUE FOR MVC4

68

• Fix cam with the ASP.NET Fall 2012 Update

• MVC4 RTM Projects need the fix

• Open Package Manager Console

• PM> Install-Package Microsoft.AspNet.MVC.FixedDisplayModes

• Use Package Manager GUI

BREAKING CHANGES (MVC4)

69

• Removed from Razor

• ModelSpan, Mvc<Language>RazorCodeGenerator (now available from

NuGet for C#), MvcVBRazorCodeParser

• WebMatrix takes over URL for Forms Auth

• Breaks MVC RTM applications

• Requires MVC3 Tools Update or

• Manual updates from http://www.asp.net/whitepapers/mvc4-release-

notes

WHAT’S NEW IN MVC5

3/18/2015 70

• Bootstrap

• Attribute Routing

• One ASP.NET

• New Membership API

• Authentication Filters (run prior to Authorization Filters)

UPGRADING MVC PROJECTS

71

• Create new MVC X+1 Project

• Copy Views, Controllers, Code, Content

• Update all web config files

• System.Web.MVC

• System.Web.WebPages

• System.Web.Helpers

• System.Web.WebPages.Razor

• Follow:

• http://www.asp.net/whitepapers/mvc4-release-notes

• Visual Studio Tooling speeds

Razor Development

• Razor Design Goals:

• Compact, Expressive, Fluid

• Easy to Learn

• Unit Testable

• Razor Features:

• No Page Directive

• Helpers and Functions

• Powerful Templating

• Extending @Html

• Delegates

SUMMARY

72

QUESTIONS?

73

[email protected]

• www.skimedic.com/blog

• www.twitter.com/skimedic

• www.hallwayconversations.com

• www.about.me/skimedic

CONTACT ME

54