Blazor Improvements in .NET 5 - Browser Storage, Virtualization, and More

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
there are a ton of great changes to blazer in dot-net 5. the speed has been improved dramatically and the product has been further stabilized but there are also a lot of additional features and options in blazer in this video we're looking at running blazer inside of an mvc project we're going to look at the new file input we're going to see our changes hot reload we're going to load 50 000 records on the screen without a problem we're going to use encrypted browser storage and a lot more this is a very full video so get ready now if this is your first video you've watched of mine my name is tim corey and it's my goal to make learning c-sharp easier i provide videos twice a week here on youtube to help you grow as a developer i also have a full set of training courses on i am tim cory i would encourage you to check out all the resources i have to offer in this video as with most of my videos i'm going to create some source code if you'd like a copy of my source code use the link in the description you might even get a special bonus just for downloading the source code let's get started right away looking at the stuff inside of blazer and to start us off we're gonna do is actually create an mvc project which seems rather weird because we want to see what blazer stuff has changed but this is the first big change so asp.net core web application hit next let's call this mvc demo and we'll call the solution name blazer changes hit create and we're going to choose asp.net core web application for net core asp.net core 5.0 so that's the latest version of mvc in the latest version.net core and we're not going to have authentication turned on we'll leave https checked we do want that now there is one additional feature if we can zoom in here enable razer runtime compilation what this does is it adds a nuget package it's not actually going to do anything besides add that nuget package until you enable it in your code but this essentially what it's going to do is allow you to reload the the razer changes when you come back to it so what happened is you make a change to the the content of the page you go a different page and come back if you saved your code changes those changes will be reflected on the page it's not quite hot reload but it's like the next time you use it it's available now so that's a nice feature we'll go ahead and enable that it will hit create so once this gets created we're going to do is we're going to put into our code this is again mvc we're going to put in a razer component just to show you that even if you have an mvc project which is fully server side it's kind of a little more old school in some ways it's it's not necessarily that cutting edge in some ways because we have usually better options for web frameworks for the front end but if you have this if it works best for you whatever you can still get the benefits of blazer and yet have them as components on your mvc page you can kind of mix and match this is something that asp.net core does well pretty much everywhere else as well we can bring in a razor page app uh so ranger page sorry into our mvc application or we can bring in api and now blazer now let's first enable that runtime compilation so we go to startup like i said it brought in a nuget package let's see that right here under packages you'll see microsoft asp.core dot mvc.razer.run time compilation version five that's a nuget package it added that's all that checkbox did that we just checked but if you go to startup you'll see down here the services.addcontroller with views inside the configure services method if we now say dot add razor run time compilation that will enable that runtime compilation for any changes we make to our our project will get reflected the next time the page is loaded rather than the whole application need to be restarted so that's a nice little um feature that makes it a little easier to work with your changes and save them while the application is live and see that reflected soon thereafter so just a little thing there it's not really the focus here but i wanted to point that out okay let's start enabling blazer server for our mvc application i do want to say right up front that you can enable either blazer server or blazer web assembly it's up to you which one you do i'm choosing to do blazer server i just prefer to have that as my um my my default but it doesn't matter it really doesn't for mvc so you can choose either one there's a little bit of a tweak to do web assembly is a couple different lines um and i will have the documentation on that in the description down below so there's any links a lot of additional links in this video compared to normal there will be an additional link for more information on components inside of mvc or razer pages just so you know we're doing mvc here but this will also work in razer pages so just want to point that out all right inside of views we have shared we have layout this is where the the actual html page gets designed okay this is this is kind of the base of our application well in here in the head we can put this pretty much anywhere we want to add bass href equals the tilde cat character and a slash and then we need to close that out so this is saying this is for blazer and says that our our website starts at the root of our domain meaning there's no it's not um a folder or too deep so you don't go you know timco.com test slash and that's where that the website starts so if you do have folder structure inside of your your domain then you need to put that folder path here and again the documentation on the website goes into more details on how you would do that not as uncommon but it is an option okay let's scroll down to the bottom here we have this this section right here it says render section async scripts and what this is is on every mvc page so every view has the option of sending javascript for just that page and that's where this gets rendered it gets put in right here for that particular page well right before this section we want to add one more script tag and script tags it's important to put them in the right order because what happens is one will override the other so if you want to make sure you have them the right order that's why we have this last it will override anything that's previous and so on well we're gonna put right before this the render section we're gonna say script and we're gonna say that the source equals and we're going to say underscore framework slash blazer server js now you may say but tim where is that file it's not there if you go looking for it you're not going to find it that's because this is actually inserted by the framework this blazer.server.js this is where our signalr works from this is where that connection gets created and set up and all that kind of stuff this is all the setup stuff around blazer it's basically like bring in net core it's just part of the the framework that you bring in so this is going to get inserted by the compiler when you produce this application for publishing next up we need to add an imports file for our razer pages we're basically kind of building out the structure of what is normally in a blazer application so if you're the blazer applications we have is underscore imports folder or file so right click on mvc demo and say add new item and we're gonna search for razer components right there but you could search for just razer the search menu and you want the name to be underscore imports and you want that right at the root so there's our imports.razer you can get rid of all the code you want to paste in this right here or type it in i'm going to paste in or save you from watching me type this all out this is boilerplate stuff so this is what you get from any blazer application or at least these seven lines this is what essentially creates the using statements for our our razor components so whenever you have any kind of c-sharp code if you look at like say a home controller you have these using statements at the top well with blazer we have an imports file and if it's at the root because you can't have more than one but if it's at the root these using statements will be applied to every razor component so you'd have to keep typing using system.net.http in every razor component so these are our defaults we're going to add one more which is using mvc demo and that will be different for every application notice that's the the name of my project that's the the root name space for our our project okay let's save that we're gonna close out of these two things and we're gonna go to the startup.cs whenever you're dealing with an asp.net core or blazer application which blazer really is part of asp.net core but whenever you're dealing with these applications you're pretty much always going to go to startup.cs and tweak something because this is kind of the heart of this of the application this is where everything gets configured initially whether it depends the injection or you know anything else that's going on with our application so it's important to know that what this file is and how it works all right the first place to go is under configure services this is where dependency injection gets set up we're going to add one thing here which is services dot add server side blazer again this would be a change if you're going to do blazer web assembly but with us doing bladed server then we add this entry right here also down in endpoints we're going to say endpoint and points sorry dot map blazer hub and this is where this is the only configuration we do for signal r now if you want to do more configuration you can but this is where that signalr configuration gets done is just right there it says okay set up that signalr connection and with that we are pretty much set up to use blazer instead of mvc now let's start with the the simplest way of doing this i'm going to right click on nbc demo i'm going to say add new item razer component and let's select counter or type counter all right put us right in the root now we're not going to leave it here because i want to show you kind of the most basic way of doing this it's just right in the root and how you'd go about doing that in your application so that that's our counter and we're not even going to give it a path to go directly there we're just going to use it as a component so let's create an int i equals 0 and then private void increment counter method inside here we're just going to say i plus equal 1. what that does is every time you run this method it's going to add one to our integer and we'll have a a paragraph here that just has current count and then the the i tag the um the i variable now i have a button with a on click that is increment counter and we're going to say class equals btn btn-primary and we'll just say click me something like that and that's really all there is to a a razor component which is a blazer object um a razor component is is really a couple different things first of all it's your html and razer syntax mixed together and then your code it's all a dot razor file now that's at the root so let's go over now to our views and let's go to our home view and index this is the index page right here and this is a you know the standard boilerplate page let's do this let's create a new div and inside this div we're gonna we're gonna put our components how we do that well we say components render mode equals server pre-rendered and then what we're going to say is type equals type of counter now it came up in the intellisense list and then we'll self-close that so it's a little bit different than using it in blazer because in blazer we would just say it's the counter so you just say right here you'd say counter that'd be it well in mvc we have to say actually this is a blazer component so let's go ahead and grab that and by the way let's specify the render mode so we're going to say the type type of counter that's the object we're going to render let's go ahead and run this so i'll hit run and once this launches we should see that on our main page is a of course a start the other window our main page is going to be a component let's zoom in here a little bit there we go there's our component says counter current count is zero and click me and if i click it notice the page isn't getting refreshed there's not a reload happening here which is what would happen if it was an mvc thing because mvc is all server side and so you have to go back to the server get the new page bring it down refresh the whole page well not with this we can just put a component from blazer onto our mvc page and kind of have the best of both worlds so if if you've got an mvc application you need to bring in some blader goodness make it a little bit nicer and a little bit more ask without having to use javascript this is the way to do it but we're not quite done here i do want to point out one thing that could be a a tripping up spot here so and that is what happens to be aside you know what i want to move that component off the root because the root gets so clogged up otherwise well let's create a new folder and we'll call this folder blazer and let's move the counter in there now you can hit yes or okay to move it it says it might take a long time it's not gonna take a long time unless you have a massive application and that it's a massive thing but normally if you move a class around if you notice the the home controller it has a name space here and that's specified in code so if you move this around somewhere else normally it reflects the path so mvc demo being the application and or the project and then controllers being the folder that's in well if you move to a different folder that namespace doesn't change automatically you can use uh templates or you can use uh intellicode another things that get changed for you but by default it doesn't change by itself with this there is no namespace specified so it takes the namespace of the folder structure without having to explicitly say this is the namespace which means the namespace has changed there's nothing in here that's saying no it's on the root so if i were to try and run this application we'd have a problem in fact let's try and do that it says no we can't do that we have an error and the error list doesn't even show an error here that's awesome but it says we've got a failed build here the type or namespace counter could not be found so this right here it's saying no i can't find that so you have to change this but if i just said blazer dot counter that's not going to work either and the reason why is because you're missing a part of the puzzle and that is the name of your project dot mvcdemo.blazer.counter now it hasn't updated yet let's do a rebuild here and see if we can get that to update the um yes enable intellicode ai intellicode based upon my selection okay so it will reflect this eventually um it got thrown off by the idea that i moved it but if we run this application it runs and once this comes up our counter is here and it works so intellisense is a little bit behind the fact that i moved it if you put it in the folder right way the first time then it shouldn't have this a speed issue but just note that when you're when it's not in the root which is what i show you first time you can just say counter when it's not in the root you have to use the full name space path which starts at mvc demo and then goes to the folder it's in and then the name of the object sometimes if you close out the page and then reopen it it will re visit the page and look at and go okay that's fine and sometimes it won't just note that that might trip you up but if you know what the full namespace is it's not a problem you can just type it out and it's fine so full name space starts with the typically the project name i say typically because you can mess with that and change the default namespace right click on your project come down to properties and you'll see the default namespace is mvcdemo which matches our project name but you can change that if you wanted to just know i might say typically that's why i'm saying it so that's it for putting components from blazer inside of a different system like mvc or razer pages all right so that's that's all of the mvc stuff i know you didn't come here to see mvc primarily you came here to see blazer so let's right click on our solution and add a new project i'm going to select a blazer application hit next we're going to say uh blazer i spilt right blazer uh server demo because we're gonna create a blazer server demo so this is blatant server 5.04.net no authentication yes https um and we're hit create now just like with any um update to.net core there have been some major speed improvements you can go and look at look at those i'm not big on doing benchmarks and comparisons because that that's kind of nebulous depends on if it applies to you and how much it applies to you um you know if if you're doing demo apps or smaller applications you probably see a much of a speed difference because it's just fast it just works but if you're building larger applications then you're going to see a much bigger speed boost with nat 5 just upgrading from net core 3.1 so we're not going to go over that but just know there's a lot of speed improvements both in blazer server and blazer web assembly what we're gonna do first is we're gonna go to the index page here and i wanna show off a couple little things well one little thing and one bigger thing first just to kind of get them out of the way and show that yes these are things we've been asking for the first one let's get rid of our survey prompt here and let's create a radio button now or radio options i don't never see sure how to say that there are options that are um you know single select so radio option you can only have one out of a set selected so let's do a let's do a paragraph first inside a paragraph we'll do an edit form and we don't have a model yet that's not a problem and we're going to say input radio group all right and i'm gonna close that out for now we're gonna put stuff inside of it just a minute but i really need to have a class to work with and some data so let's come down here and say at code and i am going to create um a simple class and so let's do this let's create the class i'm debating putting it down here just because i want to show off um this all in one spot instead of having two different spots for it but i really hate showing you demo code where i say don't do this so in the data let's do it right let's right click on data and say add class and we're going to say demo model because this really is just for demo it's not anything we're going to try to associate with a real world thing i'm going to say int h that's it um i'm just going to say that this is the age value it's an integer and that's really all it is and then what we'll do is we'll save that and come back over over here i believe that if we go to the imports that we already have oh we don't look at that add using blazer server demo dot data you know we're using statements again that's that imports.razer file i said hey everything in here is has a using statement for it so now i can say private demo model let's just call it demo equals new open close paren again that's that new syntax where you don't have to say new demo model and repeat it twice so that's we're going to do there and this will become our model that we use for our form and for our our radio so we initialize it to an empty model and now we can come up here our edit form and we can say model equals uh oops just demo like so there's some telecode saying yeah that's probably what you want and then inside the radio group we're going to say the name equals h let's call it that and then bind value whoops bind value equals this is demo.h so this is our overall model as demo we're going to bind specifically to the age property of that demo object we're going to call it h now if you're not familiar with radio inputs what they do is they have they're grouped by their name so in theory i could put radio inputs all over this page not even together as long as they point back to age we're good to go now with blazer server you don't have to do this you can take that off and what will happen is as long as you put your ra input radio objects inside of the open and the closed this radio group it's going to say i'm assuming that i belong to this parent right here so it goes to the nearest parent so just note that this is kind of more of a a nicety a formality to make sure we do it quote unquote right but you don't have to do that now input radio well actually let's do this let's say user age colon and we'll do a break which is a new line and then we'll do a for loop for i equals zero i is less than let's just do um 35 and we'll start at 21. is this you know a valid scenario probably not that's okay we're just showing off what an input could do so input radio value equals i and we'll close it out we'll say the um just say i and then br and close so what am i doing here well inside of the input radio group all this does it says everything under me will be grouped to get every input radio under me will be grouped together as the age value and they bound to this age property remember that a radio input can only have one selected value so if you have 10 values in the page then you can only select one of those 10. well in our case we're going to say okay inside there we'll say this user age we'll put a break this is not a pretty form by any means but we're saying user age colon to a break and we'll have a list of options and we'll say first of all that radio input the value will be whatever i is so start at 21 and go to 30 less than 35 so 34. and then right after the radio input we're going to put the value that that represents in this case just i again and then we'll have a break so we don't have all these inputs right next to each other they're one below the next and that's all there is to the the radio input radio we run this it should be that when we go to the main page we'll have a aha no if we set this as startup first and then we run this it should be that the main page has our radio select on it to go there and notice again not entirely pretty but i can select the values it does do this green for the green boxes around it for validation and something that i like to take off and you can take off but i wish it was off by the default but just know that's our our input radio notice i can only select one at a time whatever one i've selected is going into that property so now the age property says 22 okay so that's the input radio now i do want to show off one more thing with this let's go back to our demo model and i'm going to create actually a new class first a new class and i like to call this class in numes you can call it something else if you want but i put all of my numes typically or or group them all at least into one file called numes or one file per section called the news that way when i'm looking to debug things i know where to go it doesn't really make sense to create a whole file for just a small enum but it is what it is so let's call this car type and we'll say ford oops ford toyota honda and bmw okay and it's not public class it's publicly noom that's better and we can take the quotes off wow i really bundled that didn't i there we go looking better always helps if you start off with the right type public enum card type and it's ford toyota honda and bmw yes i know there's lots more than that this is just a demo so wouldn't that enum set up now i can use card type as a new back over here in our demo model we can say prop uh car type and just say type of car like so and now we have a new which only has four possible options or four parcel values so you probably love to set that up as a radio option that's that's a perfect sense makes perfect sense for a radio option because you can only select one you don't have a honda ford you have a honda or a ford so let's create a new input and actually let's do it on top because there's a lot of these so let's put it up top here and we're going to say that this input radio group will call this name equals car type is fine and bind value is going to be demo dots type of car then in here we're going to say car colon we'll put our our break or our line feed and then we'll do a for each we're going to say let's just say c for card type in open paren and we're going to say car type close paren oops we have our um open close square brackets first we're going to convert this so we've got we're saying we're going to cast it to an array of car type and we'll say enum dot get values type of whoops type of car type like so and we need one more close paren we should be good to go so what this does is it takes our enum which has four options and it says get all the values for that nume so get the values of this car type and that's going to come out as an array so it says array what's array of card type so that that's our list of the options for our enum each one will go into c so we're going to say input radio value equals c we can close that out and say c display that and then just break or line return so with this we've now said okay i think the first one's fork so it's got a forward and it's a value type and that's going to display fort and so on whichever one we select will then go into our value of type of car so let's see that in action once it launches there we go ford toyota honda bmw you can select which one you want to display and that's the one that gets selected so um that's how you do a new and display that on as a radio input all right so that's enough about the radio input we can um collapse that down and let's talk about the one that's probably a little more exciting to you because it's one that i keep hearing people ask about and that is file input now there has been a a nuget package for file input i showed it off in the blazer server in depth course where we used a nuget package for file input kind of as a bonus thing i said you know this isn't baked into blazer server yet but it's coming and here's what's going to look like probably and in the meantime here's one that actually works and so now it's baked into blazer there's a lot of stuff you can do this so let's start with a paragraph tag and say input file we'll say on change and let's say on input file change which we don't have yet it's okay we'll create that and we'll say multiple and we'll self close that so let's come down here and create in our code section a private a sync task the on input file change we want to have a input file change event args let's call them args like so so this is our our input and i said multiple here that i want to show just one way of doing this and i want to show the most complete way you don't have to do all of this you can have it be a not multiple in which case you can only select one file at a time but i want to show you how to do multiple because i think you can figure out how to do a single file if you didn't do multiple but with this we can say you know one file or many you can limit the type you can do a lot of different things i'm actually going to show you one way we spend all day just on this input what we're going to do is down here in the code we're going to say private list of string we're going to call this files equals again just that that new syntax which just news it up and this is going to be the files of radiant we're going to read in just text files and we're going to capture the value inside the text file and use that and display on the page okay just so you can see that yeah something that displayed the page and here's what it is based upon the files that you input so let's on this page before our edit form we're going to say a for loop for i is less than files.count i want to do a for loop because i want to have that identifier that says this is the file number i'm going to say h2 file at i let's do i plus one because you start zero so users don't necessarily wanna see file zero that kind of confuse them so file one file two is much more easy for them so therefore we're gonna add one to whatever i says note this does not change the value of i that's what this does this just changes what gets displayed then down here we're going to say let's create a paragraph tag inside there we'll say files at position i so that's going to give us each file the text of it is displayed underneath the header that says this is file one this is file two okay so down here in our on input file change this is where all the work gets done so the rest of it the file picker all that kind of stuff is all done for us all we need to do is process the files coming in so we're gonna say var max files equals two so let's say maximum you can have is two files uploaded that's it and then var max size equals we're gonna give it a pretty a large file size let's say 2 times 10 24 times 10 24. this is just for our our scanning purposes to make it really easy to understand how large that is that's two megabytes how do i know well 10 24 31 kilobytes and then times 1024 maybe one megabyte and now times two is two megabytes so i could do the multiplication on the calculator get the final value but you wouldn't know what that that means that's why we specify it this way just makes it easier to scan and read now let's do a four each on our so var file in args dot gets multiple files passing in the max files to say hey we're going to get 2 here that's all we're gonna allow now we're gonna say using var file stream equals file.open read stream max allowed size is going to be max size so this is going to open the stream for each file and say yeah but the max size is going to be 2 megabytes so anything larger than that you're not going to open it now note we're using this inline using statement so what this does is this is going to close this using statement it's going to close out the file stream properly at the end of the section it's in which in this case is this curly brace right there so that allows us to not have to nest using statements inside of using statements and have all these nested um curly braces to manage next up we're gonna say using var stream reader equals new uh we're gonna say new and then say file stream we're gonna pass that in so um let's call it reader not read oops i can't say new i have i said var here um stream reader how about that the problem is i think that's i need a i'm missing a using or a using statement here which i believe is system.io so let's come up here to the top and instead of adding to our import so we're going to say add using system.io and that seemed to do the trick yep we're good to go so that's how you do a using statement if you want just in one page it's right up there so now we're saying okay i'm gonna create a stream reader for my stream because we're assuming that we're saying this is a text file and now we're going to say var file contents equals await stream reader dot read to end a sync and files dot add file contents so we're gonna asynchronously read this file all with the end and we're gonna put the contents into our list now i have not put any safeguards in place to make sure you don't give me a jpeg and i'm reading you the text of a jpeg which would be wrong um so there's a lot of stuff you'd want to put around this i didn't want to spend again a whole video just on this file input i think that that's something we could do another time i just want to get you started in this and just point out you want to put a lot of stuff around this to protect this okay but with that we've done a for each on every file we have got the stream turned into a stream reader which we then read to the end grab the contents of that and put it into our list our list is being displayed on the page we could even do up here a um you know wrap this this thing around with a hey if it's not if it's empty then don't even show this but with the four we don't have to do it because it's not even put on the page yet so let's run this again and once this loads all right so no files have been chosen yet this is our new picker but if we go to see colon demos i have two files here let's highlight both of them hit open and now i whoops i can make a change of that but file zero plus one which would be one um this is the data from the first list and then file one plus one that'd be two these are a few my favorite movies hey there you go um so we've loaded those two files based upon the um the you know files from disk we brought them into blazer server so back back to the server side read them in and use them on our page we can also save these to the database we can do a whole lot of other things but that's the file picker again you can take off the multiple if you wanted to you can say i want to allow more than that for files you can limit what types of files you can change the size that are allowed and so much more but just note those are the basics of how to use the file input i will include a link for this as well so that um you can find out more information about the input for file for file input because there's a lot more you can do with this a lot more you can uh tweak it or play around that it's really powerful um and so you make sure that you kind of limit it a little bit and focus it in so that you don't assume users aren't going to give you bad stuff when they do so make sure that you put a lot of stuff around that to protect yourself always always always remember don't trust the user verify everything they give you and lock them down to doing only the right thing that way they don't mess you up all right now at this time i'm going to start this up one more time i want to show off let's do this let's do grab this and we'll grab this and now we have our page up it's running and i say you know what i want to say hello world i want to say um hello youtube i hit save and nothing go back out and back in nothing it's still not it's not updating i'm not a big fan of that what how do i get a a hot reload well there's a way to do that kind of and this is where you know i saw it being demoed at at the net conf and i i couldn't figure out how to make it work i mean i i tried i looked at it and this is one of those cases it really highlights the the need to test things out because i was sure i understood how hot reload worked i'm like cool as hot reload baked right into the product so now i can make changes and bing bang boom it all works but this is where i really preach over and over again you don't know something until you've done it you can watch me do it all all day long but until you actually do it yourself you don't fully know how to do it now i try really hard to show you the ins and the outs and all the stuff around it but there's still something to do it yourself it really helps you learn well it also exposes the things that you assumed that weren't true and so when i went to do this i'm like i can't get us to work i checked settings i checked preview features i made sure i had the latest version of visual studio a patch came out and i updated it it still didn't work i i couldn't figure it out and so i reached out to um the person was presenting at microsoft i'm like hey where is this i missed it somewhere you know i'm a bonehead and and he reached out and was like well it's actually not baked into the product yet and so is something that isn't in visual studio yet hot reload is not yet in visual studio for blazer but there is a way of getting hot reload that gets you 90 of the way there and that last 10 and being baked in is coming in a soon future version of visual studio so let me show you how to do the almost there or the ones it's pretty close so here's what i do i'm going to close this out i'm going to right click on my project i'm going to say copy full path i can also say open in terminal is another option which is cool let's do that let's just open terminal oh it's coming down here ah let's not do that let's go ahead open the actual um terminal which i love this is a great feature so i'm gonna say cd for change directory i'm gonna paste in that path i'm gonna take off this last section which is the actual project name enter so now i'm in the directory where my my project is okay so let's clear this again i'm going to say dotnet now if you don't know yet everything in in net pretty much is powered by the command line in fact i think everything is at this point so when you're doing anything in visual studio there's a command line version of that and a lot of times visual studio is actually running the command line version of that not all the time but a lot of times so the reason for that is not because microsoft thinks that command lines are old school and awesome which they can't they kind of do probably but the reason why command line is such a big deal is because you can automate a command line you can't really automate clicking over here and right clicking and going up properties there's tools that will help you do that but then if your screen resolution is off or it it gets wonky so with the command line you can run all these commands and automate everything which is really critical for continuous integration continuous deployment ci cd because you want to do things like build your application or bring in new get packages or even create full projects you can do at the command prompt so i've brought the windows terminal the windows terminal right now is an install you have to do through the i believe the microsoft store but you can also just open up the command window just type cmd in the run command for windows see if they hit the the windows key and just type command or cmd and hit enter and it will launch a command prompt for you or you can open powershell or your you know command line of of choice here so let's say dot net because that starts off and says okay this is a net command i'm gonna say watch run so what's gonna happen is since we're in the project that i want to start and i say net run it's going to run the project when i say net watch run it's going to run the project but it's going to watch it as well which means basically hot reload so i hit enter now one of the nice things here as well is that since i have done this it's going to launch it launch the browser too so now the the browser let's move over here let's put uh visual studio and we'll bring the command prompt back up so this looks a lot like kestrel right because it is it's kestrel so it's running kestrel on my console until i hit ctrl c which case it will stop the web server but if i come over here whoops let's there we go um if i come over here let's unpin this and it says hello youtube but let's change this back to world and i hit ctrl s to save it's gonna say hey now it's control world or hello world um it did have to reload the page which means if i had an option selected let's say bmw is selected and 29 and i say oh nope you know what uh youtube fam hit s control s then ford is selected no age is selected down here so it had to refresh my page which that's the not ideal part here because with blazer server you can have a lot of state on your page that doesn't get saved so just know that that that's kind of the downside here but with that.net watch run you can have that hot reload experience where you really play around tweak stuff i love this option when i am working with html and css specifically because i i am not an html or css guru all right i am especially not the visual part of it i can do all these things i know how to do you know i can pretty much do whatever you want me to do but coming up with the idea ahead of time and knowing oh i want you know this hex code for color and that's not me i have to play around tweak it and so what i do typically is i hit open my browser tools and i start tweaking things well with this i can come down here and say well you know that really needs to happen wrapped in a paragraph tag so let's let's do that or you know take this we move it up into here and i hit save and look at that again and go well that's that's better um you know but this probably a box around i can keep tweaking and playing to my heart's content to get what i want on the page now when you're done come back to your terminal control c to close it access the application which it's going to say attempting to reconnect it's not going to find it you can just close it out at this point so there we go and maximize that again so that's how to use the dotnet watch to get yours get yourself close to that um those minor changes the hot reload in blazer server the only downside does not remember state and so it is going to lose any changes you've made on the page okay we've got a few more to show i'm gonna try and go quickly through a few of these these are they're smaller but they're still important and before we get to the end though i do want to hang in there because the last one i've got coming is awesome virtualization and showing off 50 000 records on the page at the same not exaggeration 50 000 records on the page is i think gonna blow your mind and blew my mind um just how awesome this is so hang in there we're gonna get to that but for now let's look at a couple more smaller things so the next one i want to show off is the focus option so let's go over to the counter this is our basic counter page and what i'm going to do is i'm going to create a couple of inputs one above the counter so let's input up here and we're gonna say uh inputs and for right now i'm just gonna close this out and then i have after our click me button i have another input so what i want to do is every time i click this this button to increment the count based upon whether the uh count is even or odd i'm going to put my cursor inside of either this input or this input okay so the first thing i have to do is specify a reference to these inputs so i'm going to say private element reference test input and let's do the same thing again i'll copy this line and say test input two all right so there's now my references up here i'm going to say at ref equals test input i'll do the same thing down below where i'll say this is test input 2. so this is this right here creates a reference that i can talk to this input and this one down here creates a reference i can talk to this input now inside of my counter i can now assign which one i'm going to set the focus to so let's change this first to a async task because we're gonna do some async calling here the focus is only asynchronous so the set focus so in here after to the count i'm gonna say if current count modulus two so percent to equals zero now if you're not from the modulus or the module low i think it is character um this percent character what this does is it divides current count by this number and if there is no remainder then it equals zero so it gives it the remainder so let's just say um this was three so three divided by two three goes into two one time but there's a a leftover there's a remainder and that remainder is one well the modulus character says only give me the remainder what's left so it'd return 1 well 1 is not equal to 0 therefore it's odd but if you divide by 2 and there is no remainder it's even so await test input dot focus async so if it's even set the focus on the top input if it's odd then test input 2 dot focus async i'm just doing 2 because i want to show off it would change and not you know it's not just assume that well that's what the page does so we're gonna show off that yes this does change when you click the button every time so this can be really helpful if you want to let's say validate a form and say oop you forgot something and you can send them right back to that field on the form so let's there's a lot of other options as well but let's go look at this in action so once this comes up we'll go to the counter page and notice the input before the input after i put my cursor down here doesn't matter actually i'm going to click out of it click notice my cursor is now in this box click again notice it curses up here click in back and forth it goes so this is changing the focus because of this line right here await the element reference and focus async just a little change but something that can be really helpful in certain circumstances all right let's hit stop and now we're going to look at optional parameters and catch-all parameters so this is one that people really wanted they wanted to have the idea they could have an optional parameter right now if you put a parameter up here you have to it beforehand it was locked in that okay you have to pass a value in for that but now we can say you know what let's create a parameter let's come down here and create it first so we would first say parameter and then we would say public end with a question mark at the end which means a nullable int start count and we have our get and our set so it has to be public it has to be if you want to be optional you have to say nullable because if it's not nullable then um you've got a problem because if it's optional and they don't pass one in it's gonna it wouldn't work so now in my counter up here i can say slash in curly braces start count colon int question mark meaning the type is a nullable int and this now makes it optional and what that means is i'm not locked into having to pass in a parameter i can say you know what i'm not passing in a parameter at all in fact i haven't changed anything yet as far as the code to deal with this or anything else like that i'm i'm not going to pass anything yet i'm just going to run this and just treat like it was before and it should work so counter it goes right there click it increments the counter it changes the focus we're good to go so nothing's really changed here even though i've now added this parameter if i had made this an integer like we used to have to do and i run this and i try and go to the page it's going to say i can't find that page i'm sorry there's nothing at this address because it's looking for that slash 2 or whatever the value would be so that's where now optional parameters allow us to specify optional parameters okay if this was a string you wouldn't have to specify the type you would just say the string value and a question mark at the end okay but since it's an integer we have to specify the type including the question mark for again optional um or nullable now let's actually use this in some way let's come down here and we're going to say protected override we'll say on parameter set not the asynchronous version just the on parameter set that always messes with my i haven't figured that out yet this with my formatting you can get rid of the base dot on parameter set but here we can say if and i keep this verbose you can make this much tighter if you wanted to if depends on how easy it is for you to read start count which that's our optional value is not null i love the is not here this is this makes me so happy that makes me so happy i used to be able to say is null and we have to do an else there for not null um or you have to say uh bang equals but is not null means it reads so nicely so if it's not null then current count equals you have to cast this to an integer start count you just pass in it's nullable even though you've verified it's not null the fact that you have done some two lines means it doesn't trust it so you have to say no it really is an integer so the only difference between a nullable integer like this and an integer is the presence of null or not since we verify there is no null therefore we can say yes it actually is an int as well so now if we run this again it's nullable so we can go right to it so counter and the counter is zero but i can say slash counter slash 52 and now the current count is 52. so that's now an optional route i can take that out go back to it and it's zero so that's an optional route and there's one more type of route we want to talk about and that is the catch-all parameter and this is a we're just on the same page we want to keep this in here to show off kind of a step on each other's toes thing so let's come down here and create another parameter and this is going to be a public property of a type string happy string and where i call this let's call it custom route and what this will be is our custom route is specified so we're going to say it's going to catch all route so page equal page open quotes counter slash test let's add an extra thing here and we're going to say open curly braces star custom route like so so this is something new this star right here so we're saying custom route that that corresponds to this string right here but star means everything after this so everything after the slash you have counter slash test everything else gets captured so let's up here after our input before our counter we'll create a paragraph tag we're going to say um let's just say custom actually let's let's do an at here custom route like so let's put an h tag on top of this h two custom route just we know what the route is now again we can we can hide this if the custom route is null or empty but we're not going to do that we're just going to leave it like so and let's run this i want to show it off first and we'll talk about what this is so counter right now it says a custom route there's nothing here before counter but if i were to say slash well let's say 50 53 first and it changes the current count right but if i say slash test slash this is a test of the emergency broadcast system like so which first of all spaces aren't allowed in a url so it's gonna get that's gonna change that url to have percent i think percent 20 um for spaces but that's my my route now right see there's our percent 20s so it changed my my url but also notice this is a task of the emergency broadcast system it put that as a custom route grabbed all that well what if i did this let's take that off and we're gonna say slash test slash this slash is slash my slash test it grabbed all of it this slash is slash my slash test which looks like a normal url um a little better format we can kind of you know spread it or delineate delineate that way but grabs everything after slash test it says anything after slash test that's the custom route so it grabbed all of that how is that helpful well if you want to pass in um and handle multiple routes on one page where you say i just want to get the information off that route and i'll use that to determine what gets displayed on this page but really it's it's you know one page but it's handling multiple things you can do that now so that's our catch-all parameter now i did say i want to leave it on the same page i want to step on some toes if you just said slash counter like so notice that both of these house counters one has the start count and one has the custom route what's gonna happen here this is one of those things where testing is so important because when you do a test project and try these things out try to break it see what happens because you'll have a much better understanding of the objects that you're working with so customer routes nothing counters nothing but let's just do our slash 54. counter 0 custom route 54. that custom route overrode my um my route that has the integer even though i passed an integer so just note you really want to have some kind of you know delineate or something else if you already have parameters right off the main part of your your path so that is a catch-all parameter actually this this highlighted right here is an optional parameter this is a catch-all parameter and you can use either those now inside of of blazer all right this next one is a lot of fun and it's one that i can't wait to use in some of my applications and that is encrypted browser storage this can't be easier this is blazer server okay so it it's both server side and client side it has a foot in each world what happens is it uses uh signal r to communicate to the front end and the front just has a little bit of javascript that that talks to signalr and displays the updates on the page it's really the best of both worlds it's got the the security of your your server side but yet it's got the interactivity of the client side i love blazer server i think it's the best template microsoft has created for the web but blazer webassembly has the option of interacting with local storage because it's got the ability to talk to javascript and javascript can talk to local storage but now we have the option to talk to local storage even on blazer server and not only that we could talk to local storage and have it be encrypted so the user doesn't have direct access to manipulate and changes now to be clear you still don't want to save sensitive data to the client side but if they already have access to the data you can store it in local storage or session storage now if you're not familiar the browser has this concept of storage that the websites can use now this storage is unique to the website so that if you know microsoft.com if you were on there and they were storing stuff in local storage or session storage and you came to imtimory.com i would not have access to the session storage or local storage of microsoft.com i'd only have access to i am timcory.com local storage or session storage now there's it depends on the browser how much storage space you get but i think the um the recommendation or the default is five megabytes maximum megabytes not gigabytes not because think about this every website has access to store data on your machine also note that this storage is volatile meaning that at any point it can go away you cannot say that that your application would fail without the data that's stored there your application has to say okay i can still get data from the server this is only a convenience thing it's not a long term thing you want to use so just note that uh one of the big ways that this can be used is you know if you have a multi-page form where you don't want to save it to the database but you don't want the user to lose their place you can store things in the local storage temporarily until you get that last page and then you can you know make sure that they even if they close the browser out and come back later that you've saved all their answers and continue on that does bring up the case of local storage versus session storage and i'm giving you a blazing two-minute tutorial on this stuff okay there's a lot more to learn but i do want to get through and at least help you understand the basics so i am working on a series on html css and javascript that will illuminate all these things a lot more in depth but session storage only lasts until you close your browser once you close your browser window that session goes away and destroys everything in session storage it even will not remember between sessions so if you have a session open in firefox another one open a different tab in firefox it won't remember between the two local storage is a little more permanent and by a little more permanent i mean you can close your browser out you can close your tabs out you can come back to it later and it will still remember that it's there mostly if the user clears their session store or local storage then it'd be gone if the browser clears it out or if they use a tool that you know cleans their pc a lot of pc cleaners the big thing they do which is really a big thing is they clean out local storage caches which really is more harmful than helpful but um that's in nutshell what local storage is so we're gonna do is on this already abused page for counter we're gonna abuse a little more and we're gonna put some storage so i remember what the current count is so let's do this let's actually create a new counter because we've already abused this a lot so let's create a new razor component and we'll call this um counter two and we're going to bring in um just well let's not do anything let's just do ourselves private int current count equals zero to start off and private void increment count and we'll say current count plus equals one and then we'll we'll set up our let's actually put a paragraph current count and we'll say current count and then we'll have our button class equals btn btn-primary and we'll say that on click equals increment count and we'll say click me okay there we go so there's our our um counter two and we'll put that right in i think index is still pretty clean um yeah close enough um nope let's create our own page so we'll just say that the um the page directive or page i keep saying equals and it's not it's not equal counter to okay so that's now our url for our counter and we can go it directly we type it out that's fine oops i took away the opening tag for that or opening um angle bracket so that's counter two it's back to the basic counter page what we want to do is we want to remember this even after you close the browser so we're gonna use local storage so the first we're gonna do is we're gonna inject this user depends the injection system protected local storage we'll call it storage and it's yelling me saying hey i can't find that no problem let's come down here to imports and we'll add one more we'll add it after this virtualization here because at using microsoft.asp.net core dot components dot server dot protected browser storage okay so long name but that comes from microsoft you just type in that using statement it's better to do it here on the imports than it is to try and put it up here because that'd be so super long so this is protected local storage notice the local in there if you wanted session storage protected session storage it's called session okay we'll leave both of these in here and i'm gonna flip between the two of you and see the difference but just note that uh you only need one of those unless you wanted to store it up both for some reason which you probably wouldn't at least not for the same data okay so now in our current count what i want to do is i want to start with the increment count i'm going to say that after we increment the count so after you push the button once i'm going to await which means i'm going to change this to async task the nice thing about uh not test task the nice thing about blazer is you can change all these methods over to async without really breaking anything because the on click it handles awaitables versus non-awaitable just fine so we're gonna say await uh storage not session set async you have to give it a name we'll do that in a minute and then the value so the name should be something unique i'm going to call this counter 2 for the page dot current count so that's the page name and then the variable name that's what i'm storing here that's the string name i'm giving it you can just call it current count the problem is that if you're using local storage somewhere else in this application then you'd have to differentiate between the two so this way it's understandable the syntax is to know that it's going to be this page this variable okay that's all there is to using local storage that's it and the cool thing is that's encrypted so the user can't even read it and modify it now we're saving it but we need to read from that so let's do this protected override on initialized async wait made me make that async async task and let's fix our formatting here and no need for the return here we're going to do is say var result equals await storage dot get async let's go type int and what's the path to get well counter 2 dot current count which we just copy and paste from down here that'd be fine too it probably better because the fact that you're not having to worry about uh typing errors now current counts equals result dot success question mark result dot value colon zero now this is a one liner it's something i don't often do i typically try to break this out this would be an if statement okay so i'm saying this value here if this value is not null then put the value in currentcount result.value is the actual value coming back from result okay so bool success is a true or false if it was not successful in getting if it was successful get the value it was not successful put zero in the current count okay so that's what that's doing it's an if statement if this is the boolean true or false value this is the um the first the if successful and then this is the else statement value instead all right and either these values will then get assigned to current count so it's a one-liner but it's quick and easy and i think that that you can understand what's going on here all right so this is our counter too let's go ahead and go to shared and nav menu and just let's copy this and paste it and say href it's counter two and say counter two they don't wanna have to keep type in the browser so let's launch this this is using uh local storage so let's maximize this and counter two there's our counter two current count is zero click me works like normal right let's go to counter and click it for a few times so counters at six go back to counter two it's at four come back counter is zero and the reason why normally you don't remember things between going to page and coming back but we're reading this from local storage let's hit f12 here to bring up our browser tools and if we open up application tab you'll notice local storage here for this path you'll see let's see if we can zoom in here a little bit uh counter to dot current count the value this is the value all right that's a pretty hefty value now let's do this yeah let's just okay so there you can see the whole value let's click it a few times and watch see the values changing so it's remembering that and if we go off and we come back it remembers the value but that value is encrypted now let's copy this url let's go to a new tab and paste it in and it goes whoa and it blows up because it's saying hey let me call during on after render async um that may be an issue we can we can fix let's hit refresh here yep so let's let's do this let's well first of all let's close it out we're gonna fix that on initialize i think let me just do this on after render async um let's ride again nope protected override on after render ah first render is gotcha so um bool is it is first render or just first render okay we didn't have to specify but you know be precise then the variable name but that should work uh nope yep okay it works um counter two nothing okay oop there we go come back and that's not right so the original was correct and i'm not sure why that was yelling out before let's get back these out so let's try it again um this is a little wonky i'm not quite sure it worked in my demo which of course did um counter 2 is it 19 cool 23 cool that works um let's do this let's go to another page copy this go over here go another page counter two it says 23. this is 23. click this few times notice this is off because it's only doing that when the page first renders not sure we had that error before but it's working now um but now if we come back over and come back notice it says 24 that's because the last value i saved to was 24. so if i go to 34 and this over here is 24. if i hit click me it's going to save the value and overwrite the local storage but if i just go off and come back it now says 34. so just note that with multiple pages open you can overwrite one and cause a problem for the other but this is only for a specific user on a specific machine that doesn't see a problem so this is only for me it's not local storage is on my personal computer if you were to run the same web application on your machine let's just say i had this you know published publicly then it would not use my local storage of you using your local storage so just note that so two different pages but i i can get the value from both on either side so that's what local storage does and again if i stop it and i start again and i come back to that value it's going to still be there 34. so now let's change from storage local storage over to session storage so i'm just going to take this and wherever it says storage and change it to session those two places okay that was it let's run this and now we're gonna see that the counter two is zero i click it a few times seven come back to it it still says seven if i take this url and go to a different tab go to counter two it says zero click it a few times it says four click it a few times that says 11 back over here it still says four this still remembers 11 because each tab is its own session and if i were to close this out now where is start up since of course this is a brand new tab it's going to not have that value so it does not remember that session value hit f12 you can come over here to session storage and you'll see that there is a key there as well notice local storage is still there because local storage remembers even past the browser closing so that's still there but we're not accessing it because we're not accessing local storage anymore now you can delete this you can say clear it clears it out we come back to it and it says zero again noise didn't fail because it's fine it it says hey if i couldn't find it i'll say zero but now that's there it's gonna remember that when i come back to it so right click and say clear on on both of these and now there's nothing in either value you'll get a zero every time you come to it so that's why you don't want to rely on local storage but at the same time it can be really helpful for these quality of life interactivity things all right that's enough about that let's get to the big one and this is people often ask and you're like well tim i want to show a ton of data on the screen i want to have hundreds or thousands of records and my first reaction to that is don't because you're treating the the web browser like it is a desktop client and you can drag the browser to its knees and say well it's a browser's problem it's not the browser's problem you were pretending it's a desktop client when it's not there's a reason why desktop clients still exist because they bring you power that the web simply does not have but there is a case where you might say well yes but i have to show a certain number of records a lot of records on the screen and while i still cringe and i still say there's better ways of doing that you can pretend they're all there and just say hey fetch the next 10 when they ask for the next 10 there is still the case where you can show a lot of records on the screen so we're gonna abuse blazer today okay so if if we run this application i keep running this application but um if we run this we go to the fetch data we have five rows here with four columns okay so the dates and the times cool but what if we were to take that off to the next level so right now this is just get forecast async which is in the weather forecast service this is a dummy thing it's just creating a task for results with a range of one to five cool well instead of one to five what if we said fifty thousand and run this okay now you saw how snappy that opened up the um the blazer pagey4 let's click this now one two three four five six seven eight eight seconds or so that opens up this page but that's understandable i mean look at this this data i mean we've got data going into well wow let's scroll down here um i'll be dead okay this is october 29th of 2157 it should be mild okay i don't care i'll be dead my kids will be dead but maybe yes yes we did um that's a long way in the future all right but it took us eight generously it took us at least eight seconds probably more than that to load this data we can do better than that so let's not change anything here we're going to leave 50 000 records being generated again i would recommend against that because there's way too many records to have in the browser the browser has to remember them it it's got to work with it your browser only has so much power people complain about how slow chrome is or how much memory it takes you may be part of the problem with that if you're loading 50 000 records but you can do it and i am showing off 50 000 records because i wanna i want you to see that difference that eight seconds that took to load the page let's come down to our fetch data page we're not going to change anything about the code okay we're not gonna change all we're gonna do we're gonna comment this out all right and we're gonna put in a new section here instead of this for each we're gonna say virtualize the items are the forecasts and the context equals forecast this is basically a four each so you always said uh for each forecast in forecasts well the the list or the items are forecasts and the context is the individual item that you're going to put the value into for your 4-h so forecast that we called it you can call it anything you want so we can actually just take and copy this and paste it in so it's the same it's the same html layout it's just instead of saying for each we've changed that to virtualize and items and context okay that's it let's hit run so again we're using the same code same call same 50 000. boom it's done it's loaded and if we scroll down we can still scroll down okay it's still all there it's just that it loaded practically instantly so let's see what's going on under the covers so let's hit f12 go back to our elements here and notice this on the upper left hand corner there's this select an element in the page to inspect it click it and we're gonna inspect this first item here and that brings us up to the first row in our table and notice let's zoom out here a little bit um i know you probably can't read that really well on the screen um but what that does it shows you that you have oh how many elements that is okay not 50 000. all it has is these elements and let's open up this first one and notice where it says it says twelve seven okay so this is the number of elements we have let's scroll down here for a bit notice that first oops that that date changed to seven eight not twelve seven which seven eight is about seven or eight above this value right here on the page so we we have pretty much the same number of items on the page it's just we're changing which values are in here okay so that's all we're doing okay it's changing which elements are displayed in the page the rest aren't displayed but they're there they're behind the scenes now this can be even more intelligent it can actually fetch for your api the next 10 or the next 20 whatever you want to do and do that so it's not even like you're storing it on your user's client machine but for us we're just saying hey i want to load irresponsibly 50 000 entries on the page no problem it's gonna render it and be super responsive all right so you could you can play around this you're gonna have a problem like this notice how when i scroll it doesn't quite scroll how i expect it to be that's trying to keep up but my goodness it is all right so we're down to there is the last entry right there even though we only load a few at a time so super responsive if i hit the page up button i can just crank through these and it renders them all just fine now again just to clarify and make sure you understand the big difference here is if we if we comment this out and change this and if we run this what's happening is it's putting every item on the page even if it's not watching those items which it is but even if it's not watching those items what's going to happen is it's got to create a record on the page for each one this page now is massive we hit f12 it takes a long time to render select the first element in the list there's our row right but look it each row is actually physically on the html page show all nodes 49 500 more to show it's not even showing us in this display because there's just so many so yeah it's kind of cool that it finally put it on there but we can have a much better responsive time if we use just virtualize so just change from a for each to a virtualize and your responsiveness is practically instantaneous so again just adjust the demo make sure you got it boom page loads boom load it again load it again now if your api is not a test api that's local but instead of an actual api and you try and call your api and get 50 000 records down it doesn't matter what kind of optimizations you have on the blazer side it's going to take a while to transfer that much data across the wire so just note you won't see instantaneous response there but that's not blazer's fault anymore that's the fault of your api not well not in the fault of your api it's all of you but it's the it's the transmission of the data itself is taking the time once a day is down it'll instantly show on the page or practically instantly so that virtualized tag even though it's practically nothing when it comes to um writing the code for it it's a huge deal so it's basically a for each and it's going to virtualize your display and only display just in time what it needs to it's going to just play a few more at the top and a few more at the bottom so you can scroll and while you're scrolling us oh we need to start moving and putting new stuff in the list and moving things around and we'll do it for you so really cool really big on performance benefits again i would encourage you if you need to use the virtualize first look at your data and see if this is the best way of doing it and if you're really embracing the web or if you're trying to do desktop stuff and if you might not be able to do it a different way okay so there are ways of doing things a little more efficiently i encourage you to do that do whatever you can to be efficient but at the same time blazer is going to do what it can to be efficient as well so that your users get that really snappy experience they're looking for with the client-side interactivity and yet again the server side both safety and security as well as processing so that's my list of the things that i just pulled out from the blazer changes there's more changes beyond this that has happened i'm going to do a video sometime in the future i'm not sure um if it'd be for the holidays or not but uh just on authentication because some authentication changes have have been made um i do want to get into that and there's some really cool stuff going on there but you know there's just so much stuff to happen in blazer and part of that's because blazer is a newer thing but it is production ready people keep asking me that is blazer production ready yes absolutely if it gets released into a net release it's production ready all right so when blaze got released it was production ready immediately so blazer server has been production ready for over a year blazer web assembly has been uh production ready since may of 2020 and now that it's been out for a little while the requests for changes have come through and um we've added more things there is one more thing i i almost forgot about this i do want to cover it even though we're going long here but i think it's important stuff um there's one thing i think it was one of the most requested things of blazer and that is css isolation so let's talk that result just briefly so the idea behind css isolation is that we can make a modification to the css of just a blazer component without having to change a css for an entire application let's see what i mean by this now if you're not from the css cascading style sheets basically it's a way to format your stuff okay now let's come at the very top of site.css this is our our css document for our entire uh site for our blazer application now what if i wanted to change the the h1 tags and say that the um the color is going to be red all right if i did that then when we run the application let's run this we're going to see that every h1 tag is now red so hello youtube fam counter counter two is not that using h2 tag there fetch data is the weather forecast that is red but i'm like man i don't want to do that i want to just be the h1 tag for the counter page that's it okay or the let's do fetch data so the fetch data page the fetch data page i want that to be read but i don't want to affect any other page now what you could do is you could change just to say okay what's h1 tag but it's got a special class and you give it a custom class name that's one way of doing it but what you can do is you can come down here and see if we have fetchdata.razer well if i right click on pages and i say add new item i'm going to add a css item so i'm going to search for css and let's say fetch data.razer.css now notice it's going to nest that right underneath the razor page all right and then in here i can say let's grab that h1 tag let's cut it out of here and let's put it here and say the h1 tag is going to be red but that's just for fetch data it's named fetchdata.razer.css now let's run our application and we do we see that hello youtube fam is black so is counter but fetch data is red because that css only applies to this component all right so that's css isolation there's times for this i'm not gonna be i'm not going to use this a ton okay let me put it that way there are times when css isolation is really great especially you're bringing components together from one application to another however in general i would like to see it be mostly if you have one application then use your site.css and just style it based upon um you know custom div or custom classes so it depends on the scenario and how you're using components so don't just think this is for everything whenever you want to style a component you have to use a css isolated class you don't have to you can use site.css and then just like anything else with html you can dial into the specific items you want to modify based upon custom class names so just note it's not a removal of site.css it's just that we can now say for a specific component here's the styling i want all right so that was your bonus thing there's just so much in blazer that has changed and all the stuff that i i've talked about all works for blazer web assembly um so i said blazer throughout because it's blazer server and blazer web assembly even though i did it on blazer server but um just now you can do it on both all right so that's that's our our whole demo this is the things that i picked out of the changes for blazer in dot net 5 that i found really impactful and and really exciting i hope you enjoy it is there anything you thought i missed or you want to see covered of course authentication is coming that's a big one but is there anything else you you saw that you kind of want to see maybe uh javascript isolation which is also in here or something else let me know all right thanks for watching thanks for sticking through the end i appreciate it i appreciate a thumbs up in this video if you enjoyed it um maybe even share as well all right as always i am tim corey [Applause] you
Info
Channel: IAmTimCorey
Views: 54,549
Rating: undefined out of 5
Keywords: .net, C#, Visual Studio, code, programming, tutorial, training, how to, tim corey, C# course, C# training, C# tutorial, asp.net, .net core, asp.net mvc, blazor, blazor tutorial, blazor c#, blazor webassembly, blazor .net 5, blazor server side, blazor components, asp.net core mvc, .net 5.0, .net 5 blazor, .net 5 features, .net 5 new features, .net 5 visual studio 2019, local storage, session storage, blazor session storage, blazor local storage, blazor localstorage server side
Id: Pm4LejeJkoU
Channel Id: undefined
Length: 107min 0sec (6420 seconds)
Published: Mon Dec 07 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.