Better single-page apps with ASP.NET MVC 6
This is a modal window.
The media could not be loaded, either because the server or network failed or because the format is not supported.
Formal Metadata
Title |
| |
Title of Series | ||
Number of Parts | 133 | |
Author | ||
License | CC Attribution - NonCommercial - ShareAlike 3.0 Unported: You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this | |
Identifiers | 10.5446/48919 (DOI) | |
Publisher | ||
Release Date | ||
Language |
Content Metadata
Subject Area | |
Genre |
NDC London 201699 / 133
2
6
10
12
15
17
23
24
28
30
31
32
35
36
39
40
43
44
45
47
51
52
55
58
59
60
61
62
63
64
67
69
71
73
74
75
82
84
86
87
97
103
107
108
111
112
114
115
117
120
123
126
128
129
132
133
00:00
Software developerApplication service providerWeightMobile appWeb pageSingle-precision floating-point formatBookmark (World Wide Web)Client (computing)Server (computing)DisintegrationCache (computing)Twin primeGoodness of fitBoom (sailing)AlgebraRange (statistics)ModemSoftware frameworkMathematical singularityWeb-DesignerRegular graphMultiplication signStructural loadCartesian coordinate systemSingle-precision floating-point formatSet (mathematics)Revision controlAbsolute valueApplication service providerForm (programming)Web pageSoftware developerServer (computing)BitPoint (geometry)Mobile appPlanningCodeQuicksortData structureNP-hardFacebookGoodness of fitClient (computing)Term (mathematics)Software frameworkFeedbackComputer fontFluidOrder (biology)Power (physics)User interfaceWeb 2.0Web browserRun time (program lifecycle phase)Visualization (computer graphics)Content (media)Template (C++)Bookmark (World Wide Web)Complex (psychology)BuildingFront and back endsGame controllerValidity (statistics)Perspective (visual)Online helpScripting languageInternet service providerForestRow (database)DebuggerFormal languageProcess (computing)Physical systemData managementDifferent (Kate Ryan album)Enterprise architectureExecution unitComputer fileGoogolGroup actionMobile Web2 (number)Extension (kinesiology)Complete metric spaceBit rateComputer animation
08:46
Software developerBoom (sailing)CodeBitCartesian coordinate systemRevision controlMusical ensembleData storage deviceApplication service providerLibrary catalogCategory of beingElectronic mailing listClassical physicsSystem administratorValidity (statistics)Normal (geometry)Type theoryQuicksortWeb pageSheaf (mathematics)Form (programming)Modal logicBootstrap aggregatingComputer animation
09:57
Software developerUniform resource locatorAlgebraModal logicBootstrap aggregatingCartesian coordinate systemPredictabilityUniform resource locatorMathematicsMultiplication signWeb pageClient (computing)RootComputer fileComputer animation
10:48
Convex hullSoftware developerGame controllerPrice indexGroup actionPhysical systemScripting languageSineCache (computing)Router (computing)Endliche ModelltheorieEuclidean vectorElectronic mailing listVoltmeterStructural loadSeries (mathematics)Mobile appConnectivity (graph theory)Element (mathematics)Scripting languageView (database)CodeWeb browserCartesian coordinate systemElectronic visual displayConfiguration spaceFront and back endsSocial classRoutingInstance (computer science)Single-precision floating-point formatElectronic mailing listApplication service providerMarkup languageBitSubject indexingLine (geometry)Position operatorUniform resource locatorVolumenvisualisierungAssociative propertyLevel (video gaming)Bootstrap aggregatingBootingTwitterDefault (computer science)Computer architectureSoftware frameworkGame controllerPoint (geometry)AngleWeb pageRight angleTesselationHome pageInductive reasoningGroup actionRevision controlDifferent (Kate Ryan album)AlgebraSource codeComputer animation
14:31
Web pageSoftware developerGoogolApplication service providerAlgebraWeightGraphical user interfaceBookmark (World Wide Web)View (database)Computer fileInfinite conjugacy class propertyWindowUniform resource locatorMiniDiscMedical imagingComputer fileDirection (geometry)Cartesian coordinate systemMatching (graph theory)Computer iconWeb browserPoint (geometry)Web-DesignerBitHoaxMappingInternet service providerBootingComputer animation
15:21
Software developerControl flowConvex hullGame controllerBoom (sailing)RoutingServer (computing)MappingUniform resource locatorBitApplication service providerConfiguration spaceMobile appQuicksortMatching (graph theory)RootCartesian coordinate systemString (computer science)Single-precision floating-point formatAngleAlpha (investment)Web pageInternet service providerCASE <Informatik>Structural loadSoftware frameworkMathematical singularityElectronic mailing listClient (computing)Computer animationSource code
16:26
Software developerRoutingBookmark (World Wide Web)Convex hullExtension (kinesiology)Video game consoleLoginIdentity managementServer (computing)Software frameworkAnalogyOnline helpGame controllerMoving averageInternet service providerCodeBitInstallation artElectronic mailing listMobile appOcean currentVisualization (computer graphics)Sound effectRow (database)Level (video gaming)MappingPlastikkarteRevision controlShooting methodRoutingComputer fileOnline helpSingle-precision floating-point formatWeb pageUniform resource locatorPattern languageCartesian coordinate systemGroup actionCASE <Informatik>Computer animationSource code
17:37
Software developerRoutingReading (process)Bookmark (World Wide Web)Video game consoleElement (mathematics)Computer networkSource codeData typeComputer fontHypermediaUniform resource locatorCache (computing)Cross-site scriptingLocal ringAnnulus (mathematics)Structural loadFree variables and bound variablesUser profileGame controllerExecution unitGroup actionArc (geometry)Convex hullCartesian coordinate systemWeb pageUniform resource locatorCASE <Informatik>Extension (kinesiology)Computer fileComplex (psychology)Right angleValidity (statistics)Computer animationSource code
18:30
RoutingSoftware developerRing (mathematics)Uniform resource locatorMultiplication signWeb-DesignerValidity (statistics)Different (Kate Ryan album)Electric generatorCartesian coordinate systemClient (computing)DistanceSingle-precision floating-point formatWeb pageProcess (computing)AdditionInternet service providerCodeEndliche ModelltheoriePhysical systemComputer animation
19:27
Uniform resource locatorSoftware developerGame controllerMechatronicsMessage passingTask (computing)Convex hullFile formatWindowApplication service providerPhysical systemForm (programming)Validity (statistics)Endliche ModelltheorieCodeGroup actionObject (grammar)Server (computing)Client (computing)MathematicsShape (magazine)MetadataCategory of beingDifferent (Kate Ryan album)Rule of inferenceRange (statistics)Type theoryAttribute grammarProper mapExecution unitDigital electronicsComputer animationSource code
20:35
Uniform resource locatorSoftware developerMenu (computing)Message passingFile formatConvex hullMathematicsCodeGame controllerRule of inferenceGroup actionEndliche ModelltheorieValidity (statistics)Error messageState of matterApplication service providerFile formatObject (grammar)Right angleInformationDependent and independent variablesClient (computing)SoftwareMessage passingComputer animationSource code
21:58
Uniform resource locatorView (database)Information securityElement (mathematics)Video game consoleSource codeComputer networkCache (computing)Computer fontHypermediaCross-site scriptingSoftware developerBoom (sailing)Data typePressureDependent and independent variablesEmailMessage passingFile formatConvex hullGUI widgetAliasingString (computer science)Software testingControl flowInclusion mapClient (computing)Server (computing)SoftwareDependent and independent variablesTracing (software)Matching (graph theory)MathematicsDescriptive statisticsCodeForm (programming)Computer fileLine (geometry)Block (periodic table)Social classComputer animationSource code
23:02
EmailGUI widgetSoftware developerString (computer science)Control flowBoolean algebraDependent and independent variablesCategory of beingServer (computing)Uniform resource locatorDependent and independent variablesForm (programming)Stack (abstract data type)Buffer overflowApplication service providerElectronic visual displayInternet service providerMathematicsCodeTouchscreenMessage passingClient (computing)Lie groupModule (mathematics)Source code
24:10
Router (computing)Endliche ModelltheorieField (computer science)Form (programming)Software developerTorusHill differential equationGUI widgetDependent and independent variablesObject (grammar)String (computer science)Convex hullNormed vector spaceMenu (computing)EmailComputer networkElement (mathematics)Source codeVideo game consoleView (database)Cache (computing)Uniform resource locatorHypermediaComputer fontCross-site scriptingRankingData typeStructural loadInformation securityApplication service providerClient (computing)Module (mathematics)Server (computing)Error messageForm (programming)Coefficient of determinationValidity (statistics)Message passingCodeSource codeComputer animation
25:16
Menu (computing)Software developerRoutingCache (computing)Uniform resource locatorData typeElement (mathematics)Source codeVideo game consoleComputer networkView (database)Computer fontCross-site scriptingHypermediaStructural loadInformation securitySimulationFree variables and bound variablesClient (computing)Validity (statistics)Online helpObject (grammar)Cache (computing)BitFlow separationHome pagePoint (geometry)Structural loadSoftwareInternet service providerFront and back endsComputer animationSource code
26:16
Uniform resource locatorData typeElectronic data interchangeComputer networkSource codeElement (mathematics)Information securityCache (computing)Computer fontHypermediaCross-site scriptingSoftware developerStructural loadView (database)Menu (computing)Video game consoleElectronic mailing listMultiplication signWeb pageFront and back endsCartesian coordinate systemMenu (computing)Single-precision floating-point formatInformationBootingBitHome pageInheritance (object-oriented programming)Pattern languageQuicksortWeb browserPoint (geometry)WordClient (computing)Internet service providerOnline helpServer (computing)CodeComputer animationSource code
27:21
Software developerComputer networkElement (mathematics)Source codeData typeStructural loadUniform resource locatorCache (computing)PressureView (database)HypermediaComputer fontMenu (computing)Electronic data interchangeCurvatureString (computer science)Object (grammar)GUI widgetTorusDependent and independent variablesConvex hullScripting languageSheaf (mathematics)Group actionSineCodeServer (computing)View (database)Internet service providerFunction (mathematics)Order (biology)Cache (computing)NamespaceUniform resource locatorNormal (geometry)Goodness of fitWeb pageHome pageClient (computing)Online helpStatement (computer science)Right anglePoint (geometry)Computer animationSource code
28:37
Data typeStructural loadMenu (computing)Uniform resource locatorElement (mathematics)Video game consoleSource codeInformation securityComputer networkCache (computing)View (database)Software developerHypermediaComputer fontBookmark (World Wide Web)TelecommunicationGamma functionFront and back endsTerm (mathematics)Menu (computing)System callFunction (mathematics)SoftwareCodeScripting languageClient (computing)Data dictionaryAlpha (investment)Computer animationSource code
29:27
Data typeUniform resource locatorInformation securitySource codeElement (mathematics)Computer networkView (database)Computer fontHypermediaSoftware developerStructural loadVideo game consoleCross-site scriptingSheaf (mathematics)Scripting languageSinePhysical systemSicCache (computing)RoutingGamma functionFront and back endsFunction (mathematics)Electronic mailing listWeb pageCartesian coordinate systemBitVideo gameCache (computing)Goodness of fitPrime idealInternet service providerCharacteristic polynomialSource codeComputer animation
30:17
Bookmark (World Wide Web)Structural loadCache (computing)View (database)Uniform resource locatorComputer fontCross-site scriptingHypermediaSoftware developerComputer networkInformation securityElement (mathematics)Source codeVideo game consoleMenu (computing)BefehlsprozessorFirst-person shooterMotion captureRead-only memoryCartesian coordinate systemMultiplication signWorkloadClient (computing)Zoom lensMereologyStructural loadLevel (video gaming)Graphical user interfaceWeb pageSingle-precision floating-point formatState of matterRow (database)2 (number)Computer animationSource code
31:09
Software developerElement (mathematics)Computer networkSource codeInformation securityMotion captureImage warpingData typeStructural loadUniform resource locatorVideo game consoleCache (computing)Regular graphView (database)HypermediaCross-site scriptingComputer fontType theoryMenu (computing)Boom (sailing)SoftwareConnected spaceWeb applicationCartesian coordinate system40 (number)Structural load2 (number)BefehlsprozessorClient (computing)Profil (magazine)Multiplication signTape driveComputer animation
32:41
Information securityVideo game consoleElement (mathematics)Computer networkSource codeSoftware developerMemory managementRow (database)Resource allocationData typeCache (computing)View (database)Regular graphSicComputer fontCross-site scriptingHypermediaUniform resource locatorFunction (mathematics)Total S.A.Computer virusSoftwareProfil (magazine)Structural loadLaptop2 (number)BefehlsprozessorDivisorAndroid (robot)Cartesian coordinate systemMultiplication signInformationTriangleSurvival analysisComputer animationSource code
34:05
SicCache (computing)Java appletScripting languageSoftware developerEmulatorBoom (sailing)Matching (graph theory)BitProcess (computing)Firewall (computing)Structural loadContent (media)Server (computing)Single-precision floating-point formatPlastikkarteWeb pageClient (computing)Internet service providerOrder (biology)Artistic renderingView (database)Web browserMultiplication signCartesian coordinate systemComputer animation
34:54
View (database)SinePhysical systemGroup actionScripting languageSoftware developerConvex hullInternet service providerVacuumOrder (biology)View (database)Internet service providerExtension (kinesiology)BitFunction (mathematics)ResultantApplication service providerModule (mathematics)Server (computing)Process (computing)Source codeComputer animation
35:46
Software developerCache (computing)EmulatorConvex hullInformation securityUniform resource locatorComputer networkElement (mathematics)Video game consoleSource codeTotal S.A.Function (mathematics)Greatest elementTime zoneServer (computing)Cartesian coordinate systemExtension (kinesiology)BitProcess (computing)Web browserFunctional (mathematics)Mobile appClient (computing)System administratorPhysical systemMultiplication signUniform resource locatorGame controllerMereologyCodeLink (knot theory)Scripting languageGroup actionSheaf (mathematics)Computer animation
37:35
Information securitySoftware developerFunction (mathematics)Time zoneVideo game consoleElement (mathematics)Source codeComputer networkGreatest elementHypermediaPiUniform resource locatorStructural loadData typeView (database)Cross-site scriptingComputer fontCartesian coordinate system2 (number)Server (computing)Level (video gaming)SoftwareOnline helpComputer animation
38:26
Convex hullScripting languageSoftware developerGroup actionModule (mathematics)Physical systemSheaf (mathematics)Data typeStructural loadComputer networkElement (mathematics)Information securitySource codeView (database)Uniform resource locatorComputer fontHypermediaCross-site scriptingCache (computing)Client (computing)Function (mathematics)BitGoodness of fitCartesian coordinate systemQuantum stateMultiplication sign2 (number)Server (computing)Artistic renderingAngleSource codeComputer animation
39:30
Software developerCache (computing)Mathematical singularityLinear subspaceExecution unitRoutingFront and back endsPhysical systemCartesian coordinate systemFunctional (mathematics)Software developerSheaf (mathematics)Internet service providerBitSoftware testingWeb pageMultiplication signMusical ensembleData storage deviceSet (mathematics)Right angleWeb 2.0CASE <Informatik>BuildingSource codeComputer animation
40:33
Evolutionarily stable strategyStructural loadData typeInformation securityElement (mathematics)Computer networkSource codeView (database)Uniform resource locatorSoftware developerHypermediaCross-site scriptingComputer fontOnline helpNumberPhysical systemConvex hullScripting languageSheaf (mathematics)Context awarenessModule (mathematics)Extension (kinesiology)LoginGroup actionDefault (computer science)VolumenvisualisierungVacuumRouter (computing)Euclidean vectorWeb pagePrice indexMultiplication signMusical ensembleData storage deviceArtistic renderingForm (programming)BitSoftware testingCASE <Informatik>Web pageValidity (statistics)Client (computing)BootingInheritance (object-oriented programming)Connectivity (graph theory)Greatest elementObject (grammar)View (database)Group actionCartesian coordinate systemGame controllerCategory of beingSubject indexingQuicksortInternet service providerUniform resource locatorRouter (computing)Mobile appElement (mathematics)Term (mathematics)Revision controlNormal (geometry)Electronic visual displayMarkup languageDivision (mathematics)CodePhysical systemFunctional (mathematics)Computer fileSet (mathematics)RootMappingSocial classFigurate numberExtension (kinesiology)Online helpHome pageAreaOcean currentScripting languageProcess (computing)Web 2.0Level (video gaming)Source codeComputer animation
44:15
Internet service providerCache (computing)Software developerReading (process)Mathematical singularityNumberPlot (narrative)Convex hullMenu (computing)Text editorDependent and independent variablesSimilarity (geometry)Validity (statistics)Server (computing)Game controllerGroup actionForm (programming)Dependent and independent variablesRule of inferenceInformationGoodness of fitError messageBitMessage passingEndliche ModelltheorieRight angleNumberFile formatPhysical systemCodeApplication service providerTouchscreenMetadataClient (computing)Internet service providerSet (mathematics)Object (grammar)Web browserMultiplication signAreaSource codeComputer animation
45:58
Software developerCountingCurvatureConvex hullCache (computing)Mathematical singularityBoom (sailing)Artistic renderingRoutingPredictabilityNumberServer (computing)Message passingRight angleCache (computing)Prime idealConnectivity (graph theory)Artistic rendering1 (number)Computer animationSource code
46:50
Hash functionInformation securityElement (mathematics)View (database)Uniform resource locatorComa BerenicesCross-site scriptingHypermediaComputer fontSoftware developerEmulatorDefault (computer science)Cache (computing)Scripting languageMessage passingTouchscreenServer (computing)Subject indexingComputer fileApplication service providerCASE <Informatik>Function (mathematics)Internet service providerModule (mathematics)Ferry CorstenWeb browserComputer animationSource code
47:40
EmulatorMenu (computing)Default (computer science)Cache (computing)Keyboard shortcutSoftware developerGamma functionUniform resource locatorStatisticsData typeVideo game consoleElement (mathematics)Computer networkInformation securitySource codeHypermediaCross-site scriptingComputer fontDataflowWitt algebraScripting languageInternet service providerBoom (sailing)Inclusion mapCartesian coordinate systemTerm (mathematics)CASE <Informatik>Connectivity (graph theory)Multiplication signTouchscreenFunctional (mathematics)View (database)Server (computing)Function (mathematics)CodeScripting languageClient (computing)AreaProcess (computing)Entire functionWeightLibrary (computing)Revision controlDemo (music)Mobile appApplication service providerWeb browserInternet service providerQuicksortPrime idealSparse matrixLevel (video gaming)RoutingDifferent (Kate Ryan album)Exterior algebraPoint (geometry)Error messageDefault (computer science)Web pageSingle-precision floating-point formatCache (computing)AbstractionInterprozesskommunikationMereologyC sharpInstance (computer science)BitTelecommunicationData managementRight angleAmsterdam Ordnance DatumIntegrated development environmentStructural loadVolumenvisualisierungWordSimilarity (geometry)AlgebraStrategy gameUltraviolet photoelectron spectroscopyComputer animation
51:52
Witt algebraGamma functionFiber bundleScripting languageData typeStructural loadCache (computing)Uniform resource locatorComputer fontHypermediaCross-site scriptingInformation securitySource codeVideo game consoleElement (mathematics)Computer networkPhysical systemSoftware developerCodeDenial-of-service attackTouchscreenComputer virusMessage passingWordPoint (geometry)ForceVideo game consoleBuildingStructural loadInternet service providerCodeSource codeLibrary (computing)BitPhysical systemSocial classLoginComputer fileScripting languageCartesian coordinate systemProcess (computing)System callView (database)Computer animationSource code
53:22
Convex hullSoftware developerError messagePhysical systemElement (mathematics)Source codeComputer networkInformation securityVideo game consoleMessage passingStatement (computer science)BitGoodness of fitOcean currentRevision controlVideo game consoleImplementationSocial classScripting languageAxiom of choiceMathematicsWeb browserCodeError messageSource codeComputer animation
54:17
Video game consoleConvex hullSoftware developerInformationDependent and independent variablesCodeMultiplication signBitMereologyCartesian coordinate systemComputer fileOrder (biology)Server (computing)Application service providerCodeMiniDiscTask (computing)Web 2.0Line (geometry)BuildingNormal (geometry)Block (periodic table)Uniform resource locatorInternet service providerDemo (music)Statement (computer science)Web browserQuicksortRevision controlDependent and independent variablesStructural loadCloud computingMiddlewareRun time (program lifecycle phase)WeightTranslation (relic)Scripting languageProcess (computing)CASE <Informatik>Software developerRoutingSpiralVulnerability (computing)Source code
57:06
Error messagePhysical systemSoftware developerElement (mathematics)Video game consoleInformation securityComputer networkSource codeData typeComputer fontHypermediaUniform resource locatorStructural loadView (database)Cross-site scriptingConvex hullLoginExtension (kinesiology)ExistenceDependent and independent variablesInternet service providerInternet service providerMiniDiscComputer fileInstance (computer science)Just-in-Time-CompilerMessage passingResultantWeb browserCodeContext awarenessMereologyConfiguration spaceParameter (computer programming)String (computer science)InformationDependent and independent variablesSystem callApplication service providerTransportation theory (mathematics)Figurate numberScripting languageProcess (computing)PhysicalismMultiplication signCoefficient of determinationComputer animationSource code
59:03
Dependent and independent variablesInternet service providerSoftware developerMoment (mathematics)Module (mathematics)Convex hullComputer fileProcess (computing)Web browserRight angleError messageJava appletFunctional (mathematics)BitSineSystem callDependent and independent variablesMessage passingScripting languageModule (mathematics)Multiplication signString (computer science)Core dumpParameter (computer programming)Application service providerSource codeComputer animation
59:56
Uniform resource locatorSoftware developerData typeStructural loadComputer networkVideo game consoleElement (mathematics)Source codeInformation securityUsabilityView (database)Cross-site scriptingComputer fontHypermediaCore dumpMaxima and minimaWeb browserDependent and independent variablesMessage passingStandard ModelModule (mathematics)File systemQuicksortContent (media)CodeComputer fileMiniDiscError messageMultiplication signSocial classSoftware developerHome pageString (computer science)Computer animationSource code
01:00:50
Uniform resource locatorCross-site scriptingComputer fontHypermediaSoftware developerComputer networkVideo game consoleSource codeElement (mathematics)Information securityData typeObject (grammar)Structural loadFunction (mathematics)Density of statesCache (computing)Core dumpConvex hullInternet service providerGoodness of fitServer (computing)DisintegrationClient (computing)WeightApplication service providerWeb browserCodeSocial classFunction (mathematics)Translation (relic)QuicksortMultiplication signSystem callTemplate (C++)Power (physics)MereologySoftware repositoryRun time (program lifecycle phase)Application service providerInternet service providerCartesian coordinate systemBuildingDemosceneResultantPoint (geometry)Dynamical systemSlide ruleContent (media)Data recoveryProcess (computing)Validity (statistics)Scripting languageDivisorShared memoryTransportation theory (mathematics)Java appletLevel (video gaming)String (computer science)Computer animationSource code
Transcript: English(auto-generated)
00:05
We've got another minute or two before I'll start, but I always just like to try and find out a little bit about the audience before I get into it. So I'm guessing you people are all web developers of some kind, so I won't bother doing the whole like hands thing for that. But I am interested in what technologies
00:21
you're all using. So can I do a show of hands for Angular people? Yeah, that's like 40%. What about React? Ooh, one, really, one? Is that it? Wow, OK, I thought React was way more popular than it is. Well, do you believe that React should be more popular than that, or is that?
00:41
Right, OK, a recommendation for React there. Anyone use a knockout? Yeah, like a third of you? Nearly as many as Angular? All right, cool. And do you care about ASP.NET? Or are you here to just come up with reasons why not to use it? Yeah, a few people, all right, cool.
01:04
Great, so yeah, I'm Steve. I work for Microsoft. I'm on the ASP.NET team now. I think this is like my third time that I've spoken at NDC now, and I do like it as a conference. It's certainly one of my favorite UK and Norwegian based conferences.
01:23
And yeah, I've probably spoken about single page applications at like every single one of these things that I've ever been at, and generally people like it. The whole technology stack and that. So that's good. I worked on the Azure Management Portal for two years or something. Jacob down here did a talk earlier in the week
01:41
about the largest single page application in the world, and it was that one. So that is where a lot of my experience and perspectives on single page applications come from. And after working on that for a couple of years, I got the opportunity to move back onto the ASP.NET team and try and bring some of those learnings
02:02
into ASP.NET as a framework so that everyone else can benefit from them to some extent. Okay, so single page applications, right? You know what we're talking about. We mean building a rich JavaScript user interface so that you can deliver a very friendly,
02:22
flashy, fun, fluid user experience to your users, which is easily able to compete with native mobile and desktop applications, and yet is written in such a way that it can be shipped into a web browser, right? That's the idea. It doesn't literally have to be a single page,
02:40
but it's the general term that we use for rich JavaScript UIs. Now, these are really good, and I've been around advocating them for a while, but it can be kind of hard work, okay? The cost to you for getting this really good user experience is that there's loads and loads of stuff that you need to learn.
03:01
It's like an absolute explosion of technologies that you're supposed to know if you're a self-respecting JavaScript developer, and not just the newest version of JavaScript, ES2015, but then everything around this, this whole ecosystem for front-end build systems, for package managers, for bundling systems,
03:22
for different templating languages, for just everything that you can think about, all just to get your JavaScript, HTML, and CSS to run inside a browser. So massive, massive complexity that you've had to accept in order to build your single page application.
03:41
And the more that you do that, the more that you move all the power and control onto the client, the less and less you're really taking advantage of the fact that you've still actually got potentially this really powerful web server sitting there, and you might be not really even using it much. All you're using it for is just serving this static content to the browser.
04:00
What a waste. Well, we've been talking to people about that. We've been talking to loads of people in the community. We've particularly talked to a lot of people around about the MVP Summit time towards the end of last year. We've also been talking to the Angular team at Google, and we've been talking to folks from Facebook about React, and generally trying to collect some ideas
04:21
about what we could actually do to help. Like, is there anything that ASP.NET can even do to make this any better? As you know, historically, and even today, ASP.NET is a server-side technology. So how can a server-side technology really do anything to make things better in terms of the code
04:42
that's running in your browser? Well, we've been collecting people's opinions about that, and it's not a finished story yet. So what I'm gonna do in this talk is give you an outline of a strategy that we've come up with, and also I'm inviting you to give us more feedback. Obviously, give us feedback about this, the set of ideas that I'm gonna be showing you today,
05:01
but also please tell us what other ideas you've got for what the pain points with single-page app development are that a server-side technology can help you with. Okay, so here are some of our plans. Firstly, we want to provide a set of helpers for people building single-page apps that are actually useful.
05:21
So there are obviously some things that are happening on the server as well as on the client and these things often need to be tied up together. An example of that would be routing. You've got a server-side routing config, you've got a client-side routing config, and these things have somehow got to work together in some way. And it's the same story with validation. Of course, you've got server and client-side validation.
05:40
This is meant to work together too. But it's not just that. There's also some things that are only possible to do on the server and simply cannot be done on the client. Things around performance and efficient delivery of your application into the browser. There's just no way it can be done if you wait until the application is already loaded in the browser.
06:01
So this is where the server-side technology is supposed to help. And in order to deliver this, we want to make some special helper packages that are particular to what technology stack you've chosen. So if you are doing an Angular app, we want there to be an Angular package for you. Same with React, same with other things. Okay, that's one. Another thing is we don't want to try
06:22
and pull you away from JavaScript world because JavaScript is a sort of ecosystem. It's pretty mature now, and there's lots of great stuff there, and we want you to be able to embrace that and get the most out of it. So obviously at build time, you've got technologies like Gulp and Grunt to do your build stuff written in Node, and that's all integrated into Visual Studio now.
06:42
We want to make sure you can get the most out of that. But also, and this is a little newer, at runtime as well, there may be aspects of the JavaScript ecosystem that you want to pull in as something that you execute at runtime on the server. Now that might seem a little less familiar, but by the end of this talk,
07:00
you will have got a whole bunch of reasons about why you would want to be doing that as well. And finally, because we're Microsoft and we're supposed to do this whole complete package thing, obviously we also want to give you a really nice dev experience. So that means modern templates and also really good docs. So if you want to do the typical sort of thing
07:21
where you're pulling some data out of your database, you're passing it through your server-side code into your client-side code, and ultimately it's supposed to end up being a React form or something like that, then the docs should be really clear about how you're meant to do that. Okay, so in this talk, I'm gonna structure it a bit like this. First we're gonna talk about some Angular scenarios.
07:41
Then we're gonna talk a bit about how we're gonna help if you're a React developer. But then also we're gonna look at the underlying technologies behind this because maybe you're not doing Angular or React. Maybe you're enlightened enough to still be using Knockout. Well, we want to make sure that you're gonna have a top experience there too, but also maybe it's not even a single-page application thing that you're doing.
08:01
Maybe you just want to use the technologies we've got in some other more creative way. Okay, so let's start with AngularJS. Now, Angular 2 is JavaScript's big, enterprise-y single-page application framework, and that is in beta today. I'm sure it won't be long until they ship their final release.
08:20
And if it's even half as popular as Angular 1, then it's pretty important that we have very good support for that. So I don't have time to give a full end-to-end Angular 2 tutorial, but I will show you a little bit of Angular 2 code. And once you've seen the Angular 2 code, I can then describe ways in which we can make it better for you if you're on ASP.NET.
08:41
Okay, so let's start with an Angular 2 application. I'm gonna bring it up in my browser, and then I'm gonna show you the code that's behind it, all right? So here is my Angular application. Now, you might, if you've been to other Microsoft-y talks before, think that this looks a bit familiar. Well, yes, it's the infamous MVC Music Store application,
09:02
and this is a kind of stock application that we rewrite over and over again in all the different technologies so that we can compare how good and bad they are compared with each other. So we've done this in all versions of ASP.NET and various other things. And in this particular case, I've implemented MVC Music Store in Angular 2.
09:20
And I'll show you the code, but firstly, what it does. So it's got your typical kind of catalog navigation thing. I can navigate backwards and forwards and see what's in there. I can do things like list all the genres of music that are available and the music that's in that category. We've also got an admin section, and that has got a normal sort of paged grid like this,
09:44
and then it's got your classic data entry type stuff. So if I go in here, you can see we've got a details view, we've got an edit form, it's got some client-side validation there, and it's got a bit of a tie-in with a bootstrap modal thing for a deletion prompt.
10:01
So predictable businessy kind of application. How does it work? Well, I'm gonna show you some code. Now actually, before I show you that, let me just point out one further thing, which is the URL, okay? See that URL there? When I navigate backwards and forwards, the URL changes like you'd expect, but this is not server-side navigation.
10:20
This is client-side. We're not requesting different pages every time the URL changes. That's just Angular updating stuff. So as far as MVC itself is concerned, it doesn't know about all these URLs. It just thinks no matter what URL you request, like if I request that one, it should pop up, just all MVC itself has to do
10:40
is start the Angular application. It doesn't really have to think about the URL that you've gone to. Okay, so we want to map essentially all URLs into that Angular application, and I've done it like this. So in my app startup file, this is where my ASP.NET MVC 6 application has its routing configured. I've got a couple of route entries, and the first one is your default MVC convention here,
11:03
where you have your stuff that matches controllers and actions, okay? So if that matches something, then great, we'll serve that. But if it doesn't, then we want to render the Angular application. So I've defined this route called spa-fallback, and I've said that it should match absolutely anything at all, any URL that you request.
11:21
And no matter what you request, we're going to display the home controller index action, and that is going to start up the Angular app. So let's see that. Okay, here's my home controller, and its very clever index action, which just renders a view, and if you want to see the view for that, it looks like this. So it produces a load of script tags, and that's loading Angular 2.
11:42
And this could be optimized quite a bit, actually. I could probably reduce that down to a single script tag with some bundling or something, but that's not important for this talk. What is more important is this app element. Now app is not a standard element, as far as the browser's concerned. It's not even standard as far as Angular's concerned. It's just a custom element that I'm going to drop my application in.
12:00
And the application starts in this side, this bootstrap script here. Now that's not a thing to do with Twitter bootstrap. It's not a CSS thing. I probably should have just called it boot or boot up or something like that. But anyway, here's the code for bootstrap. You'll see it's using TypeScript, and we're importing all this stuff related to Angular.
12:20
And then we're telling Angular to start the application and do so by constructing an app component and put it in the relevant position in the UI. So the app component here, this is my app component code. I'm not going to go through it line by line, but again, it imports loads of Angular stuff and it associates itself with elements called app.
12:42
So that's how Angular knows where to put it. And this top level one, what it does is it sets up a routing config. So we'll look at what URL you're on, and depending on what URL you're on, we'll render a different component. For example, if you're at the homepage, we'll display this home component. And if you want to see the code for that,
13:01
well, here it is. It's another Angular component, which is a TypeScript class here. And the interesting things about it are inside its constructor, it gets an instance of Angular's HTTP APIs, and then it's able to make an HTTP request to the backend for some data. So it's going to request a list of the most popular albums
13:22
and when it gets that, it will stick it into this array, most popular. And then it renders its view, home.html. Inside there, you'll see a bit more markup that's familiar. So here we're displaying that big jumbotron thing, and now we can use some Angular 2 view syntax here to iterate over all of the albums
13:41
in that list of most popular things, and for each one of those, we'll produce an albumTile component. And then in turn, albumTile does basically nothing, apart from render its own view, and the view for that produces the markup for each one of those albums. So in summary, we've got the app component,
14:00
which loads the home component, which displays a series of albumTile components. So it's just components within components all the way down and that's kind of the way it is with Angular 2 and React and Knockouts and 3.2, and basically all single-page application frameworks use this kind of component-oriented architecture. Now, okay, so that's basically working all right for us.
14:23
How can we make it better with ASP.NET MVC? Well, let me start by introducing a little problem. This is a simple and boring problem, okay? The talk will get more interesting as we go through, but we're gonna start with simple and arguably a little boring. So as I'm pointing out before,
14:41
all the URLs are currently being mapped into my Angular application, apart from URLs that match files on disk. So for example, images can just be served directly. But what about URLs that should match a file on disk but actually don't? That seems like an odd thing to have, isn't it? But what about this, all right?
15:00
I think many web developers here will recognize this URL as the annoying URL that all browsers request, even if you don't have that file, to display a little icon in the title bar there. So what's gonna happen if I request that? I've got no such file, so I want it to return a 404. Will it return a 404? Answer, no, it will not. It will boot up the entire Angular application.
15:23
Because as far as the server's concerned, it doesn't know what that URL is, so it just maps everything into Angular. A little bit of a problem. What are we gonna do about that? Well, what we would like to do is go into our root config and somehow change this so that it doesn't match everything anymore. It just matches the sort of things that are likely to be relevant
15:41
in the client-side application. And it's a little bit awkward to define. There isn't a particularly straightforward way of defining that just using one of these string templates there. And so this is the first of various helpers that we want to make available if you're building an Angular app on ASP.NET. All right, so we want to ship some packages
16:02
for each of the major single-page application frameworks. And in the case of Angular, we've got one called Angular Services. And it's already out there as an alpha release on the public NuGet, so you can try that if you want to. And it contains a whole load of features that I'm gonna show you now. And the first one is to do with routing. So it's gonna solve this slightly annoying problem
16:21
about knowing whether or not a certain request should be mapped into the client-side app or not. So I want to install this Angular Services package. And it's a NuGet package, so I'm gonna go into my list of NuGet dependencies here, and I'm gonna say, let's have microsoft.aspnet.AngularServices,
16:44
current version, great. And so Visual Studio Code will say, yeah, you're gonna need to install that, so I'll say okay, and it will fetch that, and it will install it. And when it has done that, I'm gonna have access to a whole bunch of cool helpers to make my app a bit better, starting with this routing thing.
17:00
So that should be done kinda now-ish. I would like it to be done now. Now would be good, yeah, great. Okay, so now that's installed. I can go back into my startup file here, and instead of using MapRoo, I can now use this extra helper, map, map-spar-fallback-root.
17:20
Now that is just like MapRoo, except it contains a little bit of extra smarts about what people typically want to do with single page applications. So I no longer need this URL pattern anymore. I can have one because I can configure this in various ways, but I don't strictly need it, and in this case, I won't have one. So that is gonna make a slightly more intelligent judgment about whether a given request
17:40
should be mapped into my Angular app or not. Let's just check that this works. So now, if I hit reload, I would like it not to bring up that page, but rather to bring up a 404. And if we look, you'll see it is now indeed doing that. That's good. But for all of the URLs that should be mapped into the application, well, they will still work. So for example, I can go into this album slash two
18:03
and load, and it will come up there. How does that work? It's incredibly simple. All it's doing is saying, if the incoming URL looks like it's for a static file, that is, it ends with something that looks like a file name extension, then we're just gonna only serve it if it is actually a static file. So that's a simple heuristic,
18:20
which you can control if you have got more complex requirements, but in many simple cases, that's gonna be exactly what you want. So it's just nice that that's there. All right. So that's a very simple and not super clever thing that is in there, but it gets us started. All right, next thing, validation. Right, validation. Surely one of the hottest technologies and topics
18:42
in the whole of the web development world. I don't know about you, but it seems kind of embarrassing to say the least that in 2016, we are still reinventing how validation should work. But that is basically how we all keep our jobs, right? We have to reset everything and reinvent all the wheels approximately every two and a half years,
19:01
and this time is no different. So how are we gonna do server-client validation with the latest generation of single-page application frameworks? Well, let's see, shall we? So I've already got some client-side validation. Let's show that that's actually working. In fact, I showed you before, didn't I? So if I enter blank for title, I'm gonna get required, et cetera.
19:22
But what about if I want to do server-side validation as well? And of course you do. And as I'm sure you know, ASP.NET MVC has always had a reasonable system for doing server-side validation based on model metadata, and that's what I want to use right now. So let's see how we could use that. I'm gonna go into the server-side C-sharp code
19:42
that deals with this particular form. So when I submit this form here with that submit button, it's going to hit this action method on the server, update album. And it will receive from the client in the post body or put body or whatever a JSON object which is of the right shape to match this album change DTO.
20:01
And if we go to the definition for that, we'll see that this object has got various properties on it, but its actual metadata comes from this other type, album, and inside there, we've got lots of different validation rules defined in the form of attributes. Ah, go away. Okay, and one that's of interest to us now
20:21
is on price, we've got this range rule that says that the price has to be between one pence or cent or whatever we're dealing with, up to 100 units of the unspecified currency, okay? So let's see if that rule gets enforced properly. I'm gonna reload and I'm going to say, right, this album, an excellent album here,
20:43
is going to be $108, all right? And I'll hit submit and oh, your changes were saved. It did not honor the rule at all. Why not? Because I didn't write any code to make it do so. Let's quickly put that in then, shall we? So I'm gonna go back to album's API controller and look at the actual action that receives this.
21:03
Now, if you know ASP.NET MVC, you will know that there's this object called model state, and this knows whether the incoming request is valid or not, according to your model validation rules. And if it's not, I can also tell you the reasons why. So what we want is something like, if the request is not valid,
21:23
then I want to fail the response. I don't want to send back an HTTP 200. I want to send back something else. But in particular, I want to describe why this is not valid so that it can be shown in the UI. How am I gonna format that? Well, this is one of the built-in features of MVC 6. I can say return HTTP bad request.
21:43
That'll return an HTTP 400 response. But more so, we can say, I'm also gonna pass this model state object to that. And it's gonna format the validation information from that object and send it back to the client so that we can display the right error message in the client.
22:01
So let's try it, shall we? I'm gonna open the network tab so we can see the response from the server. And I will reload. And then I'm going to enter another bad value here. And let me just clear the network trace and hit submit. So now you'll see, oh, it still says your changes were saved.
22:21
That doesn't seem right, does it? But on the plus side, you can see that the server is now responding with this HTTP 400. And if we look at the actual response, it's this quite nice and convenient description of the reason why the request failed. Okay, so the server is doing the right thing now, but the client is not. The client is not acknowledging the fact
22:41
that the server rejected the request. And again, that's because there's no code to tell it to do so. So let's put some in. I'm gonna go back into my Angular app, and I'm gonna go into the album edit file here. And there's a lot too much code in here for me to go through it line by line, so don't worry about it. The only thing you need to know about is this little block here.
23:01
So this is what happens when you submit that form. It's gonna do the client-side validation, and after that, if it pass, it's going to send an HTTP request to the server, to that URL. And it's gonna get back the response from the server, having sent it the data from the form. And then we want to change the behavior based on whether the server accepted the request or not.
23:23
So we want something like if response.status is 200, then great, we'll display the change as saved message. Otherwise, we somehow want to make the messages appear on the screen. How are we gonna do that? Well, it's not obvious. This is where you end up on Stack Overflow
23:42
and start spending half a day trying out different approaches to do it. Or it would be, except that one of the nice features that we're shipping with this Angular services package is some client-side code that can do that for you as well, because it understands both ASP.NET MVC and React, sorry, Angular forms. All right, so in the same way that I installed
24:00
that package to be available on the server, I can install a similar thing on the client. So I'm gonna import that right now. So let's get here, what is it? Something like this, all right? So I want to import my ASP.NET module from this NPM module there. And now I've got ASP.NET. I can say I want to do ASP.NET.validation.showvalidation
24:24
errors, and it just wires up the server and client stuff for us. So I can say get any errors that came back in the response and display them in this .form, okay? And that should be hopefully all I have to do, and stuff will appear in the right place,
24:42
because it knows all about the conventions. So now I hit reload, and then if I enter a bad price, like this, and I hit submit, then now I correctly get at the right place in my UI the message that came back from the server. So it's not something you couldn't have invented yourself, it's just that it probably would have taken you
25:00
like an hour or two hours or three hours to try out various different approaches, and also there's some weird hacky code that makes it appear in the right place, and you would have felt bad having to write that, but the fact that we've done it for you means that you don't even need to feel bad about that. Okay, so that's some helpers for validation, great.
25:21
Okay, moving on to some stuff that I think is a little bit more cool. Cache priming, what does that mean? Well, this is where we get onto thinking about performance, and some stuff that you cannot do using client-side code alone. Right, there are several aspects of performance that I want to bring up, but the first one I want to bring up is let's think
25:41
about the network traffic a little bit. I'm gonna go back to the homepage here, and I'm going to look at this network trace, and we'll see what requests we're making. So I'm gonna hit reload, and we'll see that, well, we're making 31 requests, 2.7 megs. That's pretty bad, isn't it? Now, obviously you could improve that dramatically by doing a bit of bundling and minification.
26:02
So let's assume that you've done that, and you've improved things quite a bit. That still won't help with the following. How many requests are we making to the API backend? Okay, I'm filtering the network trace now, so when I hit reload, every time I reload, you'll see that it makes these same two HTTP requests to the backend.
26:22
It's doing one request to get a list of data to appear in the menu, that's this list of genres that's showing up here, and a second request to get a list of the most popular albums, that's this stuff that's down here. Okay, so this is a very common pattern with single-page applications, which is that you deliver the application to the browser, it all boots up, it starts rendering the UI,
26:42
and at some point, it starts making more requests back to the backend to get some data that it wants. And that's a very sensible and reasonable pattern. It's architecturally quite clean, but it's not super efficient, really, is it? So if we knew that every single time the homepage loads, we're gonna need these two pieces of data,
27:01
why are we waiting until the application is booted up before we sent it? Why didn't we just bundle that information into the initial page? That would have been a bit more efficient, right? Yeah, it would be more efficient, but it sort of messes with your architectural clarity, so you sort of feel a little awkward about doing it. But don't fear, this is something that we can make a little better.
27:21
So I want to pre-bundle these two bits of information into my page, but without having to do anything bad to my server or client-side code. And I'm gonna do this using one of the helpers that's in Angular services, and it's going to be an HTML helper. HTML helper is something that you invoke from a Razor view, normally.
27:41
And to make it available, you have to import its namespace. So I'm gonna go into this views folder, into view imports, and I'm going to add another using statement here. So it's something like this one. This one, all right, good.
28:01
All right, so I've added my using statement, and that means I can now call the HTML helpers that are inside my Angular services package. Okay, so I'm gonna go back to the homepage now, and in order to bundle the output from an arbitrary endpoint on my backend, I can do something like this. I can say, all right,
28:22
I want to pre-prepare the client-side HTTP cache with the output from this URL. So I want to evaluate that on the server and bundle it with the page. I won't have to change anything else about my server or client-side code. Now I come back over here and I hit reload.
28:41
What do we find? Instead of two requests to the backend, we've now just got one. So it didn't have to request that data that appears in the menu, but yet the data is still there. And in terms of how that's actually achieved, it's really simple, basic bare metal kind of stuff. If I do a view source, you will see that that HTML helper has produced this little script tag here,
29:01
and that's building up this dictionary of pre-cached responses, and it says in that dictionary, hey, if the client ever wants the output from a call to this URL, then don't bother going to the network actually, just pretend that you did and that you got back an HTTP 200 with this body in it.
29:21
Really simple, and it just ties in with the Angular HTTP APIs so you don't have to change the rest of your client-side code. And it means that we've got fewer HTTP requests to the backend. And of course I can do the same thing again if I don't want to have this most popular request. I can say, all right, let's also pre-bundle the output from the most popular list like that.
29:41
Come back and reload, and now we've got zero requests to the backend because it's all been pre-bundled with the page. And that's just gonna make your application have that slightly bit faster startup and your life a little bit simpler. Okay, that seem reasonable? Yeah, all right, good. All right then, so that's cache priming.
30:01
Let's move on to what I think is the coolest of the features in the Angular services package, which is pre-rendering. Now pre-rendering is a very powerful way that you can dramatically change the performance characteristics of your application. So what problem does it solve? Well, it solves largely the problem
30:20
of the application startup time. Now this is one of the slight drawbacks of doing single-page applications is that you're moving such a lot of workload onto the client that you are potentially making it take a little while before it actually starts up. Let's have a go at trying to quantify that, shall we? So I'm going to do a little timeline trace
30:42
to see how long it takes my application to start up as it is. So I'm gonna hit reload, and Chrome is gonna record what happens, and you'll see that what happens is that, if I zoom in a little bit, you can see that we move from this loading state into loaded state after roughly 1,000 milliseconds.
31:01
So it's taking about one second for our application to start up. And that seems about right, doesn't it? Because when I click this, you'll see that loading is on the screen for about one second or something. Now you might think, hey, one second, that's not too bad, is it? But it is because, one, this is a really tiny application,
31:22
yours is gonna be much bigger, and two, I've got the most insanely fast network connection you can imagine because I'm actually serving it from local host, which is not a very realistic situation for most web applications. So your application is gonna be bigger and it's gonna be on a slower network, so it's not gonna be as good for you. To try and get a sense of that,
31:40
let's throttle the network connection. I'm gonna limit it to something that's supposed to be fairly fast, 4G. 4G should be fairly fast, shouldn't it? Let's see, I'll hit load again, and I'm waiting, and I'm waiting still, and I'm waiting, and I'm still, oh, and finally, it shows up. And it's taken about six seconds there
32:00
for that to show up, and this is with a pretty tiny application. Now obviously, that's partly because I haven't bundled and minified things, so that could make it better, but the fact that you're gonna have a bigger application is going to outweigh that benefit, so that's slightly problematic. But it's not only a problem of the network speed, it's also a problem of CPU speed as well.
32:21
This is, like I say, a slight drawback of client-side rendering, which is you're moving such a lot of work onto the client that you're relying on the client being quite fast, and what if it's not? Let's try and quantify the amount of CPU time this is taking right now. So I'm gonna capture a CPU profile as this application starts up. I'll hit load, and we will see
32:41
how long this takes to show up. Actually, I've still got the slow network. Just to ensure that that's not interfering with anything, I'm going to un-throttle the network again, so we'll go back to no throttling, back into profiles, I'll clear that, I'll start another one, and I'll hit load.
33:01
Okay, so it came up in about one second. But how much CPU time did that take? Well, some of you I'm sure have got more expertise than me in reading this information, but one thing stands out, and that is this run, kind of generically titled thing. You could expand these little triangle things for quite a long time, and you'd see that
33:21
basically all of my application is inside there. So run is basically doing everything, and it's taking pretty close to half a second of CPU time. And that's half a second on a really, really fast laptop. So if you try to do this on your cheapo 50 pound Android device or an iPad 2 or something like that,
33:41
it's going to be what, a factor of 10 slower? I don't know, it's going to be a lot slower. You could easily lock up the CPU of that device with 100% usage for like five seconds or something like that. That is not particularly cool. And it can get even worse. Now this is bad, so I apologize
34:00
for bringing up such a distressing thing, but okay, imagine your worst nightmare. Yeah, now not many people do disable JavaScript, and this is a bit of a gimmick, I admit, but some people do, all right? Some people do have no script on or they've got some mad crazy corporate firewall that strips JavaScript out or something.
34:20
What's going to happen for those people? Well, I hit reload and that's what's going to happen. They're going to see this forever. That is not a very impressive user experience, is it? And if all you've got is the ability to serve static content to the browser, then you're stuck. That's the best thing that you can do. But if you're using a pretty smart server-side technology
34:42
that understands single page applications, you can do a lot better than that. So this is where pre-rendering comes in. If we can't render this thing on a client, wouldn't it be cool if we could render it on the server instead? So that's what I'm going to do. I'm going to use a tag helper that's built into Angular services, and in order to make that available,
35:01
I need to go into my view imports again. So I'm going to say that we're going to get access to all the tag helpers that are inside Angular services. Now, a tag helper is an extension to Razor syntax. So it just gives us the ability to plug in a little bit more syntax here that controls the way that the output is generated.
35:20
And on this particular occasion, what I'm going to do is I'm going to add the following. I'm going to say, all right, ASP.NET, if you really know about Angular 2, then I would like you to pre-render on the server the result of this JavaScript module. So it's going to load this JavaScript module, which is an Angular component, and render it on the server.
35:40
And so that means we don't need this loading text anymore because we're never going to be loading anymore. So if this works, then now, even though I've still got JavaScript disabled, when I reload and my server comes back up correctly, then the application will come up. So we don't need to rely on JavaScript being there necessarily for the application to be displayed.
36:03
And to some extent, it still works. So I can even do a little bit of navigation around. I can go into my admin section, I can go down here into edit, and you'll see it's all still popping up even though I don't have JavaScript on the client because it's now running on the server. Now, not everything works this way.
36:22
It's not really meant as a system for dealing with JavaScript being disabled. That's a bit of a gimmick. I'll tell you the real reason in a minute, but the part that will work without JavaScript is just simple navigation. So every time I click on something that's actually an HTML link, then obviously the browser is going to make a request for the new URL,
36:40
and the server will then pre-render the application on the server with respect to that new URL. So that's how basic navigation continues to work. But other things won't. So for example, this delete button, which is wired up some JavaScript code, well, when I click that, nothing, because there's no JavaScript. So what do you expect? But anyway, like I say, it's not really intended
37:01
for the scenario where there's no JavaScript. It's intended for the scenario where there is JavaScript, and we just want to make things a lot faster. So if I do have JavaScript enabled, then the application will still be run on the server and rendered there and sent to the browser as fully rendered HTML, but then in the background, the client-side code will load,
37:20
and when it finishes loading, then it becomes a client-side app. So the client-side code will take over and all the usual functionality will continue to work. So we've got the server and the client both execute in this application, one handing off control to the other. Now, does that really improve anything as far as performance is concerned? Well, I can try and capture another one
37:41
of these timelines now to see how it's similar or different, and if I do that, actually it's kind of pointless because we won't be able to measure anything about how long it takes because there's no loading stage anymore. It's just loaded right from the very beginning. There's no longer anything that we can say about how long that takes,
38:00
but we can say how long it takes to actually produce this fully rendered application on the server. So if I do a reload here and look in the network tab, you'll see it's taking on this occasion 78 milliseconds to evaluate all that stuff on the server. So we're down from potentially several seconds to 78 milliseconds because we're able
38:20
to run it on the server. Now, that's quite a significant improvement, but we can even go further than that because this is our Razor tag helper, which means that it's composable with other Razor tag helpers. For example, if I wanna make things faster still, I can bring in a good old bit of output caching. So I'm gonna wrap an output cache
38:40
around all of that stuff, around the pre-rendered application and the other data that we need on the client for it to run, and then when I save that, come back and reload, then I'm gonna load it a couple of times to get the cache nice and warm, and we should see that the entire time now to produce the fully rendered Angular application is down to three milliseconds
39:00
compared with the potentially multiple seconds that we would get if we had to send this down to the client and do all the rendering there. So that's a pretty dramatic improvement. Okay, that sound all right? Any questions about that? Yeah? Yes, great question. How does this actually work? How is it rendering the Angular application on the server?
39:21
I would love to tell you, but I'm not going to right now, we will get to that later on in the talk. I'm gonna show you the underlying technology behind it. So that was a great introduction to what's coming up next. All right, so we've talked about Angular for a little bit. I want to just reassure the one person in the audience who uses React and everyone else who's going to use React in the future
39:42
that we've got great support for that as well. So, and then we will go on to this final section of the talk where I'll tell you about the underlying technologies and how you can use them in other ways. Okay, so just like we've got an Angular services, we've also got React services and that has basically the same set of functionality.
40:00
So let me show you just so you can get a sense of how this is similar or different. So I'm gonna shut down my Angular application here and I'm gonna start up a React one, which is very, very similar. So let's get that going here and I also need to start Webpack in the background. Webpack is a build and bundling system
40:23
for front-end technologies and it's very popular with React developers. You can learn more about that some other time, not in this talk. All right, so I've got my React application working there. Let's try actually bringing that up now. It's not the MVC music store this time. It's something rather a lot simpler. It's just this grid, very boring,
40:42
but it will act as an adequate test case for what we want to do. So it has paging here and again, it's client-side navigation and client-side rendering and it's also got this form with a bit of client-side validation in there. All right, simple stuff.
41:00
Can we do the same things for React that we can do for Angular? Yes, obviously, but how does it really work? Okay, not very many of you are too familiar with Angular, it seems. So let me give you a quick sense of how the Angular application hangs together, even though we can't go through all of it in too much detail. So let me bring up the code for that.
41:21
Now, in just the same way as before, I have installed this helper package. I've installed React services there and that gives me roughly the same set of functionality that I did have for Angular. And for example, I've got the same maps bar fallback root helper thing, which is just as applicable to React as it is for Angular and that is saying for basically every URL
41:42
we want to display home controller index action. And if we're looking there, home controller, again, all it does is just render its view and the view for that is pretty simple and similar as well. Now, this time I have bundled all my JavaScripts there into this single file using webpack, like I mentioned, and also we're producing this div with the special ID.
42:03
Now, that is something that will be used by the boot up system so that it knows where to put the application. And to show you that, I will go into my boot client JSX file. Now JSX, for those of you who don't know, is basically the same as JavaScript, but it's extended the syntax a little bit
42:22
to support these element literals right in the middle of the code. So it's kind of a bit like your XML literals from VB, if you're into that sort of thing. And in terms of what that actually means, well, it's just syntactical shorthand for instantiating objects and then assigning properties to them. So this is going to new up a React app and it's gonna set a property on it
42:41
passing that value into it there. So it's just a simple shorthand way and it's very useful with React, but you don't have to do that if you don't want to. Okay, so I'm importing all the React stuff and I'm saying React, I would like you to render one of these React apps and I want you to stick all that into this React app element that you saw a minute ago. And as for what React app itself actually is,
43:02
well, if we go in there, well, React app extends the normal base class for React components. This is an ECMAScript 2015 class, the current version of JavaScript, if you're not familiar with it. So it looks a lot like TypeScript, but it's actually JavaScript. And inside there, I'm using the React router feature.
43:21
React router is a routing system, you could guess that. And like the Angular one, it looks at all the different URLs that might be requested, matches them up to the client-side routing configuration, and based on which one, it's going to render a different component. So in this case, on the homepage, we're gonna render a people grid. And the people grid looks like this.
43:42
Again, it's a React component, so it inherits from that base class. And when it renders, it's going to produce this markup that you were seeing earlier. And amongst that, we've got a griddle element. And griddle is a third-party grid component for React. So it's just handling simple things
44:00
like being able to sort by column and doing the paging bar and stuff at the bottom. Just saved me the trouble of implementing that myself, although I'm sure it wouldn't have been too hard. Okay, so that's how the application fits together. Can we do the same stuff that we did for React? Well, I've already shown you that we had the map-spar-fallback-root thing. So we've already seen that.
44:20
Okay, next thing, validation. Is that gonna work in a similar way? Yes, it is. Let me show you. So we've got this edit form here. Let's say we wanna do some server-side validation on that. Here's my People API controller. This is the endpoint that gets hit when you submit that form. And this object, PersonDto, is what we're gonna parse the incoming request into.
44:42
And just like before, I'm using MVC's typical kind of model metadata system to define a validation rule for my favorite number. Has to be between one and 10. And if your incoming request is not valid, then we're gonna send back another one of these HTTP bad request responses to the client. Okay, and then on the client inside PersonEditor,
45:03
just like before, there's too much code for me to show you all of it, but it's only this simple bit that's really relevant to us. So when you submit the form, we're going to send a put request to the server with the same, with all the model information. And when the response comes back, if the server says that's good, HTTP 200 okay,
45:22
then we will display a nice, yeah, that's good message. And if not, then we're going to parse the message that came back from ASP.NET MVC, and we want to make those errors appear on the screen. Now it's even easier with React than it was for Angular forms, because React forms, or sorry, formsy forms,
45:40
which is a third party forms thing for React, gives us this setErrors method. And as long as your error messages are in the right format, then they'll appear at the right place in the screen. And by not actually a coincidence, the response from ASP.NET MVC is in exactly the right format for that. So in here, if I enter a crazy favorite number,
46:02
now clearly that's insane and no one should be allowed to have that as a favorite number. So when I hit, oh, I expected a different message. Let's try that one more time. Okay, there we go, that's what I expected. It must have been cached in the browser or something. So that is the message that's coming back from the server there, as you would expect, appearing in the right place.
46:20
All right, so that works in a predictable kind of way. What else? Cache priming. Well, I'm not going to show you that. Two reasons. One, it would be the same as what you've seen before. Two, I haven't implemented it yet. So, but you know what it's going to do, right? It's going to be exactly the same and it'll be really easy to implement. So just take it for granted that that's the same. Pre-rendering.
46:41
Can we render React components on the server in the same way that we can render Angular ones? Obviously we can, otherwise I wouldn't be talking about it, would I? So let's check that that's really true. All right, so just like before, I'm going to do the same silly party trick of turning off JavaScript, even though it's not completely realistic.
47:01
And I will reload and you'll see that we get the loading message on the screen again. And we will see that we can use the same technique as before to render on the server. So I'm going to go to my index.cshtml. And just like before, I don't need this loading message anymore. And I can have something like this. ASP.NET, use the React module
47:21
to pre-render on the server the output from this module here. Where the module in this case is a JSX file. Now React services knows all about JSX. It knows how to transpile them, it knows how to evaluate them, et cetera. So that's all going to hopefully render successfully on the server. Let's see if it does.
47:41
Back in the browser, hit reload, and it comes up. So even though we've still got JavaScript disabled, we've still got our application working because now it's running on the server. But the more important scenario is when you do have JavaScript enabled and we can render on the server for the first time to get it up on the screen really quickly, but then the client-side code takes over
48:02
and you've still got the full functionality view of your application. And in terms of timing, well, it's basically like what we had before. So, and this time it's taking 31 milliseconds to render that React component on the server. A little faster than Angular, I suppose, or it's just simpler in this case. And just like before,
48:21
you can wrap some output caching around that if you want to make it super fast. All right, so that's doing React stuff on the server. Now, following the very relevant and insightful question we had before, how does that really work? How are we doing this stuff on the server and how could I do this myself with some other technology if I wanted to?
48:43
For example, if I wanted to do it for Knockout or if I wanted to do it for some other new thing that whatever JavaScript hipster person has invented this morning, well, you're gonna want to have access to the underlying technology, right? So we've got a couple of packages that we are making available here. One is called Sparse Services
49:01
and one is called Node Services. And these provide the infrastructure that is needed for doing that sort of thing. So what do they do and what can you actually make use of that? So I've just shown you Angular Services and React Services. And what I wanna do for the rest of this talk is show you how you could build your own thing that's a bit like that.
49:21
And like I said, you can do so by taking advantage of the Sparse Services package. And what that contains is any helpers that we think are relevant across all the different single page application technologies. So that's things like the Sparse Fallback route and it's things like cache priming or anything else that is relevant across all the different technology stacks.
49:41
So you can take that. But that's not enough on its own. Sometimes you might need to be able to execute JavaScript on the server. That's how the Angular Services manages to render Angular apps on the server. Similar with how we managed to do React Services. Now, obviously an alternative would be to do it all in .NET.
50:01
So you could, if you are crazy enough, you could try and implement in C Sharp your own entire version of Angular. That would be madness, but you could do it if you wanted to. What would be a lot more sensible would be to have a way of running Angular itself just the original JavaScript code on the server. Same for React Services. Because both Angular and React ship with the relevant libraries
50:22
to be able to execute in an arbitrary JavaScript environment, not just the browser. And this is where the Node Services package comes in. Node Services is a general abstraction over the ability to execute code inside Node as part of your ASP.NET application. So it's talking out to Node.
50:40
Now you could do this yourself if you wanted. You don't need to use Node Services. If you wanted, you could start up your own instances of Node, and you could figure out your own inter-process communication method, and you could figure out your own process lifetime management, and you could figure out your own error handling strategy, all that stuff. But the point of this package is that you don't have to, because we've done all that.
51:01
It's just a general way of talking to Node. And it's pluggable as well. So we've got various different ways of hosting Node, various different transport layers between ASP.NET and Node. Most of the time, you won't have to think about that. You can just use the defaults. But if you've got certain interests in different ways of hosting Node on different servers or something like that, then you can control it at that sort of level too.
51:22
Okay, now let's see an example of using Node Services to do something of our own that's got nothing to do with Angular or React, okay? So I'm going to switch over to my third and final demo. So I'm gonna shut down the React Grid example. I'm gonna move over to this other demo. Now as for what this does, the clue is kind of in the name.
51:44
It's called ES2015 Transpilation. But before we get to that, I just wanna show you something that I'm very, very proud of. It's an application I built. It's really cool, okay? Let me just load it, and you'll see. It's pretty awesome, right? So what it does is it displays on the screen this word
52:01
that was carefully chosen by marketing and a PR agency, the word hello. But that's not all. There's one more thing, right? If I look in the console, it also displays a message there. And I think you will agree that this is a pretty cool thing, right? This is potentially the starting point for my billion dollar console logging
52:20
as a service startup there. But if I want to go out and attract venture capital funding for my startup, I'm gonna need to be able to demonstrate that I'm building this with the very latest technologies. So I'm gonna need to build this with ES2015 code. So let's see if we can do that. First, I'm gonna let you in on the secret sauce behind how my Astonishing application works, right?
52:43
Here's what it does. Inside my view, I've got this word hello. So that's how that bit works. Also, I'm using the system.js library to load this other JavaScript file called main.js. Now system.js, it's just a modern way of loading JavaScript. You could have just had a script tag if you want to.
53:00
But anyway, I'm using this to load main.js. And inside that file, main.js, this is where the real magic happens. It's got a console log statement, okay, cool. But if I want to do that with ES2015, I'm going to want to use some cool features like classes and other stuff like that. So I've started work on that already. I've made this file greeting.js and that has an ES2015 class.
53:24
ES2015 being the current version of JavaScript, which has features like classes, okay? So here's my greeting class. It's got a getMessage method and that's where I'm returning my new 2016 message from there. And if I want to actually get that message and use it in main.js,
53:40
then I'm going to need to change my implementation a little bit to something like this, okay? So now I'm using an import statement here to import my greeting class and then I'm using that to get the message to log to the console there, okay, good. Shall we see if this actually works? Back in the browser, I'm going to hit reload
54:00
and it does not work. I'm getting errors. These errors are very, very wrong. They're very misleading and confusing and it's got nothing to do with the actual reason for why there's an error. The actual reason is that my browser does not support ES2015 code. So it doesn't know what the import statement is,
54:20
for example. So if I want to be able to make my browser actually support this code, then the normal way of doing that is, as I'm sure you know, to do some sort of build time transpilation step. So you'll use Gulp or Grunt or Webpack or some other thing like that to convert the CS2015 code into plain old boring ES5 code
54:40
that runs inside normal browsers, right? You knew that, yeah? All right, so we could do that. We could do it as a build time step, but then, well, you've got to set up your build time task to do that. You've got to remember to make sure it runs every time you change your file. You've got to have these temporary compiled files on disk somewhere. You've got to make sure your application loads
55:01
the transpiled files. You've got to make sure that you somehow deploy these transpiled files to your server, to your cloud host or whatever. You need to worry about if the browser's cached an old version of it. You need to worry about if there was an old version on disk that you were supposed to have deleted before you did build or something like that. All this faff that you don't really want to deal with. Wouldn't it be cool if you didn't have to do
55:21
any of that stuff and instead, your web server was smart enough to just auto transpile the file as part of producing the response. That would be quite nice, wouldn't it? But in order to do that, you would need to be able to run a transpiler at run time. And the problem with that is that all the transpilers are written in JavaScript, which is very sad
55:41
for us .NET developers, isn't it? You feel left out at all by that? But you don't have to feel left out because we can use Node services to use whatever features that we want from Node.js as part of our ASP.NET application with pretty good performance as well. So what I want to do is add a little bit of middleware to my application.
56:01
Now middleware is something that's gonna sit in the middle of my application request processing pipeline and deal with transforming requests and responses and stuff like that. And in this case, it's going to auto transpile any JavaScript files that get requested. So I'm gonna go into my startup file here. I'm gonna add a little bit of code like the following.
56:20
So I'm going to add this little block of code here that says whenever someone tries to request something that's under this JS folder, I want to run the following code. And the code I'm gonna run is gonna look a little bit like this. So what I'm doing here is I'm firstly saying on this line of code, I want to get the full URL that the user has requested.
56:43
And then based on that, I'm going to ask Webroot file provider to check whether or not there is any actual static file under the wwwroot folder in my application matching that path. And if there is, I'm gonna do something cool with it. And if there isn't, I'm gonna return a 404.
57:02
So let's just check that that actually works before we start relying on that and get into problems with demo. So I'm going to request js slash blah.js. Now there is no such file on disk. So I want this to come back with a 404 and it does, good, we're happy. And if I request a file that does actually exist on disk,
57:22
like greeting.js, then it now displays this message to do transpile the file, okay? So we're capturing the requests and we can now do something with them. And what I want to do is use node services to do some dynamic transpilation. So I have installed the node services package here,
57:40
as you can see from NuGet. And then I'm also getting an instance of node services. This uses ASP.NET's dependency injection system. So as part of that configure method, I'm saying, please give me an instance of inode services so that I can do stuff with that. And when I've got one of those, I can do something like this. I can say, let's just get IntelliSense
58:01
going on here first. I can say node services dot invoke. And then I want to invoke a method in JavaScript and it's gonna return a string to me in this particular occasion. And it's gonna be a method exported by a file called transpilation.js, which is the name I want, okay?
58:23
And I can pass any parameters I want into this call. And on this occasion, I'm gonna pass file info dot physical path so that we know the path to the JavaScript file that we want to transpile, okay? And that's gonna return a result to us and it's gonna do it asynchronously.
58:40
So we'll await for that result to come back to us, right? And then when we've got that result, I can say something like await context dot response dot write async result. So we're gonna write that to the browser as the response. Sounds all right? So now let's create this file transpilation.js
59:01
where we can put some JavaScript code. So I'm gonna go here, new file transpilation.js and I don't want quotes around that because I have no idea what would happen if I did that. So let's get them away, okay? And now I can write a little bit of JavaScript in here that's going to get invoked. And the JavaScript I'm gonna have is going to be like this.
59:22
All right, so here's my initial effort at this. It's a JavaScript module here and I'm going to export from this module the following function that can be called from ASP.NET. And it's gonna be asynchronous, so it will take a callback to invoke when it's done. And following normal node conventions, the first parameter to the callback
59:41
will be any errors that have occurred. And there aren't any errors because hey, why would we have errors? So I'm just gonna return null for that. And then for the actual response, I'm gonna return this string. Hello, you requested whatever file it was that you requested. So now, if this actually works, then when I reload here, it should pass the call through into.
01:00:00
node and get the response back out of there and serve that to the browser and it does. So we're getting our message back from node in the browser now. So now we're in node world, we can do anything that node can do. We can import any of its modules from NPM. For example, we can import these two modules, the file system built in standard module
01:00:21
and the Babel module. Babel is a sort of general purpose bundler transpiler thing and we can use it for transpiling our ES2015 code. So this time, instead of displaying that silly message, I am going to have this code. I'm saying, okay, we'll use the file system module to read the contents of that file from disk
01:00:41
into a string, and then we'll pass that through into Babel to get it to transpile the file. And when it's done that, we'll send the transpiled code down to the browser. So now back in my browser, when I hit reload, instead of the message, I should get the actual transpiled code in the browser. So when my user goes to the homepage, instead of the errors, this time,
01:01:03
they should get hello from the ES2015 class. So it works. So now, as a developer, I can just write my ES2015 code. Don't have to think about it being built. It's just going to get transpiled on the fly. Now obviously, there are some performance implications for that. So if you're going to do this, you're going to want to put some sort of output caching around it so
01:01:20
that you're not paying any per request cost for the actual transpilation. Okay, now to clarify, I'm not saying that you should stop using Grunt and Gulp and other build time things, because actually those things work really well, and people are very successful and happy with them. So that's absolutely a very good way of dealing with transpilation. I'm not saying to not do that. I'm really just using that as an example of the fact that we really can pull in arbitrary infrastructure from Node.js world
01:01:46
and use it in a nice, simple, and high-performance way as part of our ASP.NET application. And that is, of course, how the server-side rendering for Angular and React works. We're just making calls into the Angular and React APIs for rendering, getting back the rendered result as a string,
01:02:01
and writing it down to the browser. So it's pretty simple, and you could have set that up yourself. All right, so we're basically out of time. I'm just going to quickly wrap this up now to summarize by showing you the same slide I showed you before. Here's the stuff that we want to do to try and help. We want to try and provide a bunch of helpers that are genuinely useful. And we're doing that by basically asking people for what the pain points are and trying to put them into some packages.
01:02:22
We've got the Angular services package. We've got React services. And we will be very, very happy if you want to make some packages for other technologies, too. And obviously, they contain a bunch of helpers for things like routing validation, pre-rendering, that sort of thing. Also, we want to make sure that you can really get the most out of all the JavaScript infrastructure that's out there,
01:02:43
both at build time and at runtime. Hopefully, most devs are not going to have to work with Node code unless they want to because it would be really easy for you, for example, to say, hey, I'm going to make my own NuGet package that encapsulates the ability to do dynamic transpilation of JavaScript code.
01:03:01
And you publish that to NuGet. Someone else installs that and uses it. They don't really have to mess around with the Node stuff. You've just provided that facility to them in a really convenient way. You can maybe make your package for, you know, whatever stuff you need to do that you need to share amongst the various teams in your company. And they don't have to deal with the low-level stuff. You can package that up. And finally, obviously, we want to do all the other peripheral stuff that's quite important, actually, when you think about it,
01:03:25
like documentation and templates and that sort of thing. So there we go. That is all I'm going to have time to talk about in this talk. I hope that was useful for you. The NuGet packages that I've talked about are all public and on NuGet already. And all the demo code that I showed you in this talk is up there in that GitHub repo that I've referenced there as well.
01:03:46
So come up and ask me any questions if you want to afterwards. We don't really have time for questions now. And please remember to evaluate the session on your way out so you can control whether or not I'm here again next year. Use your power wisely on that one.
01:04:03
And have a good party this evening. Enjoy the rest of your week.