Modern Web UI with Blazor WebAssembly - Steve Sanderson - NDC Oslo 2020

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay cool right then so welcome everybody to this session thank you for choosing to join us today i hope this is going to be fun and useful to you so my name is steve and i work at microsoft i'm on the asp.net team and the main thing that i focus on at the moment is this thing that we're talking about today which is blazer and i know many of you will know about this already but i think also a fair number of people may not so what i'm going to do in this talk is i will try to balance a little bit there some intro content with some deeper investigations into certain features of blazer which i hope you will all find useful so let's get a look at what we're going to talk about so like i said we're going to start with a little bit of introductory content to set the scene for anyone who's not quite sure what this stuff is about and why they should care but that will only take a few minutes uh we will go through some getting started content and then we will look for the majority of the time into what stuff is in blazer webassembly which we have just shipped so what is blazer and what is the point of any of this well let's imagine that your job as a web developer is to build a rich web application that your customers can use and maybe they need to use it inside a regular desktop web browser maybe they need to use it as something more like an installable app on their mobile devices and within this application let's imagine that you need to do some really sophisticated stuff you want a very rich ui with many many different kinds of things going on there you're going to have grids you're going to have sidebars dialogues wizards drop-downs all all the things that you could ever reasonably have inside a ui but you've also got lots of other concerns to think about as well you've got things like uh authentication authorization other security things you're gonna have to deal with things like localization you're gonna have to deal with uh just many many different cross-cutting concerns that affects modern application development so how are you going to build something like this what kind of technology would you use well if we go back in time a few years then your only option to build something that runs in a browser would have been one of these kinds of things a javascript framework and you would have had to write your code in javascript or something that compiles to javascript like typescript and that's fine that's all very well people did that for many years and have been successful with doing that but it's not it's not great for our industry if that's the only option that people have got because within software there are many other kinds of languages frameworks programming paradigms and it's a bit of a shame if they're all shut out from web development but the good side of this the good news is that thanks to modern web standards we're not actually limited to just using one kind of language anymore and this is where blazer comes in so blazer is a ui technology for the web that lets you build these kinds of rich web applications using net code and this is thanks to the ability to do things like real-time web sockets connections and the ability to run code on webassembly inside browsers and what are the advantages of doing that why would anyone care about this well probably the the main advantage that people do care about is the ability to use the c-sharp language and net so c-sharp has been well established for many years as being a highly productive and effective language to build large-scale robust applications which is the sort of thing that many of you are doing today and alongside that comes with some really excellent tooling and ide support you know arguably best in industry type tooling there with that we have in the form of visual studio and visual studio for mac and vs code and then separately from that there's the rest of the dotnet ecosystem which is a very consistent and stable world so unlike some other software ecosystems.net is not changing every few months it's not constantly getting you to build stuff according to different best practices that are always changing dotnet tends to be stable over long periods of time and that's uh kind of deliberately by design so hopefully the investments that you make into building a rich web app with net will pay off for many years to come okay so when you build a blazer application there are two main ways that you can deploy that and host that on the internet the first mechanism is something called blazer server and we have had that for a little while so that shipped initially with net core 3 back in november last year and in this model your net code your blazer components run on the server somewhere so probably in a cloud environment somewhere and whenever you want to display some ui in someone's browser or wherever you want to react to something that the user does all that information is being sent over a real-time websocket connection via signalr so that things can update on the fly so that's been around for a little while and many people are using that but the newer version of blazer which just shipped about three weeks ago at build is blazer webassembly and that's something that people have been waiting for for a long time and in some ways that's a simpler model because in this model your.net code and your components just run directly inside the browser on a.net runtime that we have compiled to webassembly so that it can run in standard uh web browsers desktop and mobile without the use of any plugins just purely on modern web standards okay so that's a super high level overview of what kind of problem this is supposed to solve now the cool and exciting news is like i just mentioned that blazer web assembly is now fully released and that is quite a big exciting and relieving thing from my point of view because i've been working on building this uh with a team for more than two years now i think we've done more than 17 pre-releases and got a lot of feedback from the community and built up a big group of enthusiastic users so it's a big uh excitement to finally have that to be fully released and supported for production use if you want to do that then the way to get started is pretty straightforward because i think a lot of people have seen this already i'm not actually going to give you any demos of creating new projects from scratch if you want to see that you can go and find many other videos online or read the documentation probably the best way to get started is to go to blazer.net and that will give you some setup instructions for whichever kind of coding environment and ide you wish to use so if you want to use visual studio on windows or for mac or whether you prefer to use visual studio code all of those are going to work really well for you and you can find information about that on blazer.net but in this talk i don't want to focus too much on getting started because i'm aware that many people will already know about that so let's think instead about some of the cool and useful features that i've shipped just a few weeks ago in blazer webassembly and to do that we're going to need to have an application that we can build and i've got a starting point application for us to work from it's a fairly sophisticated application that will demonstrate a lot of different features and i will go through showing you some of the code behind each of those things and along the way hopefully we can add a new a few new features to the application so you get a sense of what coding with this is like so here's a an application starting point for us it's something called car checker which is a demo app that we've been using uh quite a bit over the last month or so and i'm going to start it up in my browser now and then i'll quickly talk you through what kind of scenario this is meant to be for so if i start that up i'm going to use ctrl f5 to start that in the browser without the debugger because that makes it come up nice and fast and when it does come up you'll see that the only thing that a user can do when they get started is login so who would log in who is this application for anyway well this application is designed for a car rentals company so you know what it's like if you go and rent a car you go you take it you drive it around for a week or so and then you bring it back to the car rentals company and you have to check it back in with them and some staff member comes out and they look at the vehicle and they check things like have you fueled it up correctly have you added too much mileage have you caused any damage anywhere on the car and they need to record information that they find when they're looking at the vehicle that they're checking back in so that's what this application is for so the person logging in would be a staff member at the car rentals company so let's pretend that we're a staff member now and i'm going to log in and i've already registered a user account for myself so i'm going to put the username and password in there and then when i get back to the application you'll see that i'm now logged in and i've got a few more things i can do for example i can go and manage my account or i can go and synchronize stuff with the server via this update button and we'll talk more about what that means in a minute but let's pretend that a customer has just brought a vehicle back to us and we need to check it now well we can start typing its license number in and we get this nice autocomplete kind of thing going on there so let's say it's this one here and i'll click on that and we'll now get into the vehicle details editor okay so what the staff member would do probably is they would go and look at the mileage on the car that's being returned and they would want to update that inside the ui so maybe they come along and they type in some absolutely crazy implausible value and you can see we've got some forms and validation stuff kicking in there so let's just change that to something else maybe this customer returned it just half full so we'd want to track that and you can see over here on the right that this save button has now shown up and that's because blazer has a built-in forms and validation system that keeps track of the state of the form and it knows that there are some unchanged unsaved changes and then the the staff member could also walk around the vehicle in real life and compare it with this 3d view which shows us where damage has already been recorded on the vehicle and they can maybe add some information about any new damage that they find so let's imagine that there's some problem with this headlight here they could choose that and then they could go into add note maybe they try to save it without typing any description in and they get validation and they can then type in some actual description like absolutely destroyed okay and then they could save their changes on there and then they could hit save again and that will save the changes back to the server and if they don't remember to press the save changes button then we'll know that we should prompt them to save their changes or not in this case i'm not going to all right so quite a lot of things going on inside the application there and one other thing i want to show you before we get into the code is how this might look on a mobile device because this application is really designed to be used from mobile because you know when some staff member is walking around vehicles in a parking lot they probably don't want to be carrying a laptop with them so let's see how this might look on an actual mobile so i've got my phone here and i'm going to share the screen of it with you so there it is and then you'll see that i've got this chart car checker application installed onto my home screen we'll talk about how that works in a minute and when i go into there then the same application will now show up and this is still blazer running on webassembly but we've got slightly different layout now that makes use of the mobile screen you'll see it doesn't have any browser address bars and it fills up the whole area of the screen including the curved areas and i can still go and find a vehicle i've got a slightly different layout now but i can still use the the 3d view i can still go and add some information about damage and if i was to try and add a photo you'll see the browser's native ui for taking photos or using the photo picker appears and excuse the french on that we'll talk about localization a little bit later on okay so that's a quick overview of what this application looks like let's now start digging in to some aspects of how it's implemented okay so we are going to go through six different areas of the code and in each case i'll show you a little bit about how it's been set up and then hopefully we can also add some extra features to really understand how this works a little bit more and the first area that we're going to look at is authorization okay so security in general is obviously a very important topic in web applications and there's quite a lot of functionality that's baked into blazer as a client-side technology as well as asp.net core as a server-side one and they all tie together so let's have a look at a little bit of that now i already showed you that i could log in and in fact i can get back to the account management thing from here and if i do click that if you're an asp.net developer you might recognize this kind of ui already this is asp.net core's built-in identity system which is a built-in way of managing user accounts and letting users set up all the stuff to do with their account and two-factor authentication and stuff like that and the point i'm showing you this is just to say that that is fully integrated with blazer webassembly so when you create your project you get various options about how you want to do auth and one of those options is simply to use the asp.net core server side identity system but that's not the only option that you've got we actually support the use of any open id connect compatible provider so if you want to do login using azure active directory or google logins or any other oidc compliant provider then you can absolutely do that and that's going to work great but in this case i'm using the backend asp.net core application as my login system okay so that's how users can log in but there's more that you need to do than just let people log in for example you may want to lock down access to certain server side data endpoints that's kind of the whole point of security in the first place really we don't we don't care so much about what people see in the ui as we do about what data they can access and modify on the back end so how does that integrate with blazer webassembly well let's have a go at locking down our application a little bit in fact let's start by looking at a bit of the code that we've got in here so inside my solution you can see i've got these three projects i've got this client project here which is the actual blazer webassembly application and we'll be going through quite a bit of the code in there soon we've also got this server side project which is an asp.net core server which is dealing with the actual data storage in the login system now blazer webassembly doesn't require you to use asp.net core on the server it can be used with any server side technology or even non i'll show you that later but if you are using asp.net core on the server then you get some pretty good integrations now the first one of these that we're going to talk about is auth so let's imagine that i want to lock down my server side data a little bit i'm going to go to this vehicle controller here that's a server-side mvc controller that exposes things about the list of vehicles that have been changed or lets you actually put a modification to a vehicle record in the database and at the moment it has no access control at all it's just publicly readable and writable by the whole world and that's not really what we want so i'm going to add this authorize attribute here and if you are an asp.net developer already you will recognize that that's the standard way of limiting access to a controller and because i haven't provided any extra detail that's just going to lock it down to users who are logged in i could add a i could implement more detailed policies than that if i want but this is good enough for now you can access this if and only if you are logged in so let's see how the client application behaves now that data is protected if i reload over here then initially it might appear to be more or less the same but if you look at the bottom you'll see it now says could not sync okay what's actually going on there let's have a look at the network trace here so when i click this retry button a couple of times you'll see that the server is responding with the status 401 not authorized and that's because the servant now only accepts requests from people who are logged in and so you might be thinking well i am logged in look we can see the username right there clearly you are logged in why does it act as if you're not logged in well the answer to that is because i've deliberately disconnected an important part of how these two things integrate just so that i can show it to you so by default when you create your project with this kind of auth it automatically knows that whenever you make http requests to the back end it should include the auth tokens that the server has issued so that the server knows you're logged in but in this case i've commented that out just so that i could show it to you so let's see where that actually is if i go into my program cs this is inside my client-side application that runs on webassembly and this is where all the global configuration of my application works and i don't expect you to recognize or understand all the code that's in here but i just want you to notice that this line of code here is commented out uh i'm going to uncomment it just so that it goes back to its default behavior that the project template gives us and what that does is it says whenever we're making requests to the base address that is the url that the application is hosted on we're going to include the authorization tokens that's what this particular message handler does and that's there by default normally so now if i have that back to its usual behavior and i hit reload then instead of getting these error messages hopefully it's now going to go back to working normally and if i click this button a couple of times you'll see that the server is responding with 200 okay and if we look in there in slightly more detail we can see in the uh request headers that we're sending to the server from the client here that we've included this authorization token which is what the server issued when we first logged in so that's why the server knows who we are and of course you can do way more stuff with auth than just that but that hopefully gives you a bit of a sense of how things can be wired together between server and client and it illustrates how things are set up by default okay so that's enough about that let's move on to an another area that i think will be of interest and this is to do with code sharing and i'm going to talk about this from a couple of different angles because this is one of the real strengths of blazer webassembly and the first way that i'm going to talk about it is to do this sharing code across different parts of your own application code your own solution so if we go back to yes here and we look you'll see that like i mentioned before we've got these two different with three projects we've got the client project here we've got the server project and finally we've got this shared project now shared is nothing special there's no magic going on here that's just a plain old net standard class library but one of the great things about having.net as a full stack language used on both the client and the server is that you can trivially share code between your server and client just by having a common project that both of them reference and that's something that people very commonly do when they're defining things like domain model classes that want to be used in both places so in this example here i've got for example the vehicle class that defines all the different properties and metadata that we have about vehicles we've also got this inspection note class that's what i've been creating whenever i add information about damage to one of the cars okay now this shared uh set of classes is used for quite a lot of things we're using reusing it in a few different ways so the first way is that this structure of properties and metadata actually defines the schema of the server-side database the sql database on the server has its shape automatically set up to match this these classes and all of these properties and metadata so that's the first way the second way it's used is that this metadata is uh defines the server-side validation rules that are enforced every time we make http requests to the server thirdly they define the client-side validation rules that are used within the ui when you're editing a form and fourthly they define the shape of the traffic that's exchanged between the client and the server so the actual network wire format and all four of those things are always guaranteed to be consistent because they are all coming from a single source of truth there so that's a really handy way of sharing information and just to illustrate that let's add an extra validation rule so far adding photos has been optional let's say that it's now required so i'm going to say that photo url is now mandatory and there's going to be an error message if you don't give it and i'll say all damage must be photographed like that okay so let's rebuild that and that is now going to change the behavior of both the client side and the server side code let's see what that does so if i go back now and i hit reload so that the changes are applied then i'll go back into that car that we saw earlier and let's say that i want to uh have a look at this part of the car the body front left okay i open this now and you'll see that actually i want to edit the existing note rather than add another one okay so if i try to hit the save button now you'll see that i can't save it anymore because all damage must be photographed okay so how can we add a photo of the damage here well i could click on this take new button but nothing happens when i do that because i haven't actually implemented the ability to pick photos yet and that takes us on to the next way of sharing code which is sharing code across the entire ecosystem using nuget packages so blazer webassembly does not have a built-in way of picking photos or files but there are nuget packages that can do that for us and i'm going to do that inside my client project right now so i'm going to right click on there and go manage new get packages and i'm going to search for a package to do that and i happen to know it already exists that i want this one blazer input file and that is a general purpose way of picking files uh which could be photos or something else and then you can do whatever you want with the data that's inside those files okay so now how am i going to use that well we haven't actually looked at any of the blazer component code yet so if you have never seen this before it's probably worth explaining a couple of details about that within this class within this project here i've got all these different razer files each one of the razer files is a ui component it combines both markup and logic and you can build a structure of these components to define your application ui for example we've got this vehicle note editor okay and if we go in here this is quite a sophisticated component so it's if it's the first one you've ever seen then i apologize for kind of throwing you in at the deep end here but within here you can see that there's a lot of stuff going on we can use the dependency injection system we can render other components hierarchically we can use html markup to render stuff we can have uh c-sharp expressions in the middle of our markup that all get rendered efficiently and down here you can see we can have c-sharp source code to implement the actual behavior of the component and there are many different ways you can do that but in this case what i want to do is add a photo picker here we've got a bit of an html form where it's got this caption about photo and it's displaying validation messages and such now i've just added that package called blazer input file that means i've got access to this input file component that's inside there initially it's qualified by a namespace i don't really want that so let's take that away and i'm going to add a using statement here so that i've got the blazer input file namespace available and now i can just use input file directly without having to qualify it now to save us a bit of time i've already prepared the code that we want here so i want to have an input file and i'm also going to say that i only want to accept images so that will affect how the behavior in the browser is and it makes mobile devices use the photo picker and so on and then i'm saying when you pick something i want to call this c-sharp method handle photo selected which doesn't exist yet hence the red squigglies so i'll scroll down to all of my event handlers and i'm going to put in the logic i want and the logic i want is this the user is going to pick one or more files in fact they can only pick one files because i didn't make it a multi-select so we'll take the first source file from the list and we'll represent it as a jpeg image with this certain maximum resolution and we'll read all the bytes from there we're going to use that as the photo on this particular domain model class and that will hopefully satisfy the validation rules and it will also get stored in the database so when i rebuild that and i go back and reload hopefully i'll be able to actually pick a photo this time and then i will be allowed to save my changes so here i'm going to click on this and now you see a file picker appears and the actual behavior and appearance of that depends on what kind of browser or operating system you're in on a mobile it would use the photo picker and then i'm going to hit save on that and you'll see the validation rules are now satisfied but i have only satisfied validation rules for this one thing these other two notes don't have photos yet so when i try to save that you'll see i get this error message here the server is rejecting this change because it hasn't satisfied all of the rules on the server so that just goes to show that validation isn't enforced on both sides of the wire so to get past that problem i'm just going to delete these other two things so i don't have to have photos on them and then i'll hit save and now this time my change will successfully go through okay so there's quite a bit of code sharing stuff next topic to talk about javascript interrupt so why would you want to do that well kind of the point of blazer is to let you write as much of your application ui logic as possible in.net code so why would you want to use javascript well there are lots of reasons actually one of them is that the javascript ecosystem is massive and there's loads of really useful third-party components that you might want to use in your application and blazer applications should be able to use those perfectly easily and another reason is of course that the browser apis themselves that are built into the browser are exposed in the form of javascript and you're going to need to be able to call those from.net so blazer is a system for calling javascript from.net and for calling.net from javascript and i can show you examples of that now so the first example that i'll show you is something you've already been seeing which is this 3d view here now this 3d view is not actually implemented italian.net code behind the scenes there it uses the 3js library which is a very popular third-party javascript library for 3d rendering so how is that being used within our application well let's have a look if i go into this index component here you'll see not index vehicle editor you will see that we've got this scene view component and that component is not defined in my project that's actually coming from a nuget package and that wraps up everything that i need to integrate with 3js in a reusable way that makes it feel just like normal.net programming so i can pass stuff to it like what skybox to use what object to render i can tell it what stuff to highlight which in this case is the damaged parts of the car and i can even have a callback so that my c-sharp event handlers fire when the user clicks on a particular part within that 3d view so that's how you can pull in third-party dependencies that wrap up all the javascript interrupt for you so you don't have to see any javascript yourself so that's the easiest way of doing javascript interrupt but there'll also be some times where you need to write your own javascript code and interact with it directly from.net and so let me show you an example of that right now an example of that in this application is to do with how the data is stored because one of the business requirements for this application is that it needs to work offline and i hope the reason for that should seem fairly natural since the person who's inspecting these cars will probably have to walk out into a big car park or parking lot to inspect the vehicles they can't really guarantee that they're going to have wi-fi access all the time so the application needs to be able to start up when you're offline and you need to be able to make edits and save them even while you're offline and then eventually synchronize those changes back to the server so to port support that we've got a client-side database and i can show you that in the browser dev tools here it's something that's built into browsers called index db okay and if we look in here you can see here's information about my local database it's called vehicles it's got three tables in it one in which we track the local edits that we haven't sent to the server yet another one that's got some general metadata and then finally we've got this table in which we synchronize all the stuff that we know about the database from the server and this synchronizes incrementally so it's perfectly okay even if it's a giant database and we're getting the list of all the cards that are known at this particular rental location which might be quite a large number but we need all of them so that the user can search through that database even while they're offline okay how does this work then so how do we get access to indexeddb from netcode well there's a couple of steps to that and one of them is to write some javascript and i've got this javascript file here called local vehicle store and if you've not seen this sort of thing before it might seem a bit scary at first but it's not too bad because we've only got 36 lines of code in there and within that 36 lines we're defining the database schema up here and that includes these three tables that i showed you as well as their primary keys and indexes that sort of thing it's pretty simple api and then we've also got these general purpose functions for accessing that data so we can get stuff from a particular store or table uh we can get all of the things we can put stuff in there we can delete stuff and we've even got this application specific query here which we're using for autocomplete so when you type stuff in uh it's going to search for the first n items in a given table and then to access this from netcode we've got a class here called local vehicle store and i'm making that available through dependency injection to any part of the application that needs it and that uses this ijs runtime interface to make calls into javascript for example if we want to get a list of the outstanding unsynchronized edits we simply say get me everything from the local edits table and deserialize that as a set of vehicle objects and when we want to synchronize we can say okay get all the local edits for each one of them i want to do a put request to send that to the server and then assuming that the server says this was successful then delete the local copy of it and when we're done with all that we'll finally fetch any unsynchronized changes from the server so hopefully you'll see that that's a fairly neat self-contained way of interacting with javascript stuff from.net code whether it's your own javascript or third-party javascript okay so next topic debugging obviously there will be times where you need to be able to debug your.net code but is it actually possible to debug.netcode that's running on webassembly inside a browser well my application up now with the debugger so i pressed the f5 key and that tells my ide to start up a new instance of the browser which is listening for debugger connections and then visual studio will connect to that and start my application up in it and now hopefully i can start doing some debugging okay so let's see what do we want to debug well let's go back to this car we've been working on here and you'll remember that i added a photo a little bit earlier and you might have noticed this detect damage button shows up so what's that well this is kind of a bit independent of blazer really but it's kind of cool so we put it in anyway when you press this detect damage button it sends the photo data to the server which then runs a machine learning model an ml.net model over it to detect any damage to the vehicle that shows up in that photo so we know whether the customer has to be charged or not so that's a bit separate from blazer but it gives us an example of something that we might want to debug so let's see we'll go into our client-side code that runs on webassembly we've got this component called damage detection and this is where that stuff happens when you click the button we've got this c-sharp method called perform damage detection and i'm going to put a breakpoint in there before we send the data to the server and another break point when we get the response back from the server but i also want to debug my server side code too so in the server code i'll find the detect damage controller which receives the data and i'll put a break point in there as well so now in the browser when i click on this detect damage button we'll find that it hits a breakpoint inside our code that's running on webassembly and we can do the usual debugging type gestures so i can hover over here and see that this flag is currently false but if i step then the flag now becomes true i could also step through this process of getting the data and sending it to the server but i'm just going to press f5 and now we will hit the server-side breakpoint and we can continue debugging and stepping through the server-side code and see how the machine learning model does its thing but i'm going to press f5 and then after the model runs it's going to hopefully hit the breakpoint back in the client-side code as well and if we want to we can now even hover over this damage detection result and we can see that the server is saying that this car is damaged and we've got this certain confidence level and we can press f5 one more time and now we get back into the browser ui where you can see that the ui has been updated and we get the information that we expected so the point of me showing you this thing is just to say that yes you can use the normal debugger gestures to debug your client-side code but more than that you can do full stack debugging where you've got code running across server and client and you can step through that process of calls that go between server and client and debug them both at the same time now i only showed you that in visual studio but the same thing is true in vs code as well it's a slightly different process for launching the debugger there but it also does work and you can go and see the docs if you want to know more about that so let's close that instance of the browser down and i'm going to get back into the one that doesn't have a debugger attached okay right then so that's uh enough about debugging what else should we talk about well how about internationalization if you are building an application for a global audience it's probably not good enough to just build it in one language and have one fixed set of culture settings you probably need to account for the needs of different users around the world so let's imagine that we are a large global car rental company and some of our users speak a different language let's try changing the browser language settings if i go over here into the language settings you can see that i've got english uk as my default preferred language but i'm going to change it so that spanish is my preferred language and now back in the browser when i reload hopefully you will see that the whole ui now shows up in spanish all the strings which are built into the application are in spanish but of course not any strings that are entered by the user because we're not you know magically translating stuff it's only stuff that we've provided translations for it's perhaps a little more obvious still if we go back to the homepage where we've now got bienv bienvenido sorry about my pronunciation there and all of the ui is in spanish including things like validation messages okay so how does that work well again if you're an asp.net developer you'll find this quite familiar let's see how this thing is set up if i go into my di configuration again you'll see one of the services that is registered in this application is called is the localization service and in this case i've configured it to say i want to get my resources out of this directory called resources and that's inside my application here so you can see i've got these resex files inside that directory and that provides translations and i can create as many of those as i want for different cultures and blazer webassembly is smart enough to only download the ones that are applicable to the current user so you don't have to worry about adding loads of them okay now to understand that a little bit more let's add a bit of extra localization because there's one part of my application i haven't localized yet if i open this you can see that these two strings manage account and log out are still in english so why are they still in english if we go to where that is defined which is the login status component here you will see that we have got these two strings that are hard-coded in english and i want them to be translated how can we translate strings well i'll show you in a different component that is already translated so the index component and you can see that it injects this string localization string localizer service which is the same thing that is available in asp.net core on the server and you can use that to access the contents of your resex translations so for example to translate into license number all we do is we simply read that string out of the localizer and that will fetch the best translation that's available for this user and if there is no translation available it will just return the string exactly as it is okay so let's have a go at using that inside login status you can see i've already injected it here at the top there so now instead of just hard coding that string i'm going to read it out of the localizer okay so i've done that now let's see if that is sufficient to get the translations to appear in the ui okay so we just wait for that to rebuild and then i'll go back and i'll hit reload and we'll see if our text now shows up in spanish the answer is no it does not it's still english why is that well the reason for that is because localize is not magic and it doesn't actually know how to translate stuff until you actually provide translations for it one of the nice things about it is that if it doesn't have translations it's not an error it just uses the string as it is so for you as a developer you're not required to speak every language in the world uh you don't have to speak anything other than your own language you can just use localize around all the strings and from your point of view nothing will change but it means that later on someone can come and provide translations for whatever set of languages they want and they will just show up at the right time so let's add some translations for these two i'm going to go to my spanish res x file here where you can see i've got all these translations already these were helpfully provided by javier on the team who not only speaks spanish but also uh implemented a lot of blazer so thanks for that have you and i am going to go and put these two entries in there manage account and log out and then i'll use the translations that i've been given so this is the spanish for log out i'm going to put in there and then similarly for administrate account or manage account that will be there okay so i'll rebuild one more time and this time we actually do have the translations so hopefully when i reload instead of seeing that text in english we're going to see it in the user's preferred language at last and there we go we do so it's now fully in spanish and of course if i want to and i do i can switch myself back into english and when i reload then everything is going to go back into english again okay so it's not limited to just translating strings blazer webassembly also has globalization support in by default so when it comes to things like entering numbers formatting dates and such like uh they will automatically respect the user's thread culture and we also have support for time zones as well so when you print out dates and times in local time zone uh they will show up correctly for the given user okay so that's quite a lot of stuff there let's move on now to our final topic and this is the area where everything we've seen so far kind of comes together into one beautiful harmony that is progressive web apps so what's a pwa well if you didn't know a progressive web app is a way of building and using a web application that behaves a little bit more like a native desktop application so that means things like it can be installed into your operating system and it'll show up on your start menu or your home screen or dock whatever your os has it also means that you could use it offline without needing any kind of network connectivity and other things like the ability to send and receive push notifications from a back-end server even when the user is not actually using your application so quite a lot of stuff that pwas can do and blazer webassembly is a true client-side technology so it can take use take advantage of all of that stuff and we've got support for this built into the project template when you create your project you can simply check a box to say if you want it to be a pwa and that's what i've done when i set up this car checker application and one of the things it does is it creates this file called manifest.json and that tells the browser that you want this application to be installable and how it should look when it is installed so you specify a name you can specify an icon and various things to do with theme colors and by virtue of having that file if we look in the browser closely you'll notice that we've got this little plus button up here that is offering to let the user install this into their device so if i click on this install button right now you'll see that rather than being inside the browser it now shows up in its own separate window now behind the scenes this is a browser but as far as a regular civilian end user is concerned it's it doesn't look like a browser it doesn't have an address bar and it can have whatever styles in it you want so it behaves and looks just like a native application including things like being launchable from the start menu and you can put it on your home screen or doc or whatever so if i start searching now for car checker you'll see that's there on my start menu since i'm in windows and i can start that up again and this is still blazer running on webassembly and it's going to have all the same functionality that we saw before okay now what about running offline does this thing work offline and how could we test that well like i said behind the scenes this is still a browser even though it doesn't look like one and we can still get into the browser dev tools if i go to inspect here you'll see the browser dev tools show up okay and using these i can simulate being offline if i want to so there we go i'm telling the browser i want to pretend that we're offline and i want to simulate what it's like to start the application when you're offline so i'm going to right click and go to refresh and this will be just like what happens if you've got no network connectivity and you try to start the application does it work the answer is no it does not we just get an error message saying you're not connected so what on earth is going on there you're probably thinking uh you've just been telling me that pwas can work offline and that this is a pwa so why doesn't it work offline that's a very good and fair question the answer is that within the project template by default we've set it up so that offline support is only enabled when you've published your application not in development and there's a good reason for that the reason is that when you've got an offline first pwa whenever you change the application those updates aren't applied instantly they're rolled out asynchronously in the background and that could be very annoying to you during development because when you make a change you want to see your change show up as quickly as possible you don't want to wait for some kind of async process to take place in the background so that's why we only do offline support in uh production so if i want to show this to you i'm going to have to actually publish my application and i can do that quite easily i could do it from my ide in visual studio but i kind of like doing publishing from the command line because i find the experience a little bit faster to just type in one command like that so that's going to publish my application to a folder on my local hard drive and it takes a few moments because during the publish process this is when we run tree shaking or linking as we call it to strip out all the unused code it's also when we do a very aggressive form of broadly pre-compression to try and shrink your application down even further so that'll take a few moments to go through and when it does go through i'll be able to just run it locally so hopefully that'll be finished in a few seconds and i can stop trying to fill in the time come on there we go right it's done so now i'm going to switch into the directory where it's been published to and i'm going to start up the uh application in its published form so that's now listening on this port 8080 and i'm going to go into my browser and start that up okay so here that comes and let's see if that's working well i've slightly confused it by changing the port so i'm going to log out and log myself back in again so let's go back to log in and i'll use the same account as before okay so now hopefully i'm fully logged in to the production published version of my application and i could install it again as a pwa if i wanted to uh either on desktop like i showed you before but it's just the same to use in a browser so just like before i'm going to go to the dev tools and i'm going to say i want to simulate being offline okay so i'm offline now and then just like before i'm going to reload the page and we'll see do we get an error this time the answer is no we do not get an error it actually comes up and it works well we've actually got quite a few errors in the network trace because we're trying to talk to the server but we can't anymore because there is no network access and hence we cannot synchronize our changes but the application is still going to work you know i can still search through the database i can still go in and start making edits like i'm going to change the fuel level to half here and then i'll hit save and you can see we still can't synchronize but we know that there's an onsen edit and that's safely stored in the local indexeddb even restart the application and my edit is still there and available so let's imagine now that as a staff member we've checked in a few cars without network access and then we walk back over to where the office is and we resume the wi-fi connection so we get wi-fi signal back and now we hit the retry button again what happens is that our changes now go through happily so that's all very nice okay so that is making an offline capable pwa with blazer web assembly all right so that's all the main features i want to show you one last thing i'm going to show you really quickly is not really a feature so much as it is just a kind of an inherent behavior of client-side web applications which is that we can do pure static file hosting i already said that you don't have to have net core on the server if you don't want to you can host a blazer webassembly app from any server technology whether that's node or ruby or python anything else that you like it's fine you can even host it from a web server that doesn't even support dynamic code you can host on a pure static file host like azure static sites or github pages anything like that that you want and to really prove that to you i'm just going to show you a blazer webassembly application which is running on github pages so if i go to this git repo here which is public you can go visit yourself right now if you want to this is the default blazer project template deployed to github pages so there's no server side code going on here if i follow this link here this is the the standard blazer project template which you've probably seen before if you've ever seen any blazer stuff or tried it yourself and it's all fully functional it's running out.net code on webassembly inside the browser it supports navigation and it supports deep linking everything that you'd expect and it even serves it efficiently with broadly pre-compression the way this all works is mainly it just works naturally because as far as the server is concerned we're just serving static content and the browser doesn't care what it where it comes from the only bits that i've customized for github is that i've added a few things in order to make it served more efficiently with broccoli compression and if you want to come and see how that works then just come and look at this git repo and see exactly what i've done but the real point that i'm making is that when you choose to build a blazer webassembly application you've got a huge amount of flexibility about how it's deployed and if you want to you can have globally distributed static file hosting completely free using something like github pages and blazer webassembly can be served like that so that's nearly all that we're going to have time for we might even get time to answer a few questions so if you have questions i would encourage you to come and post them in the slack channel here and i'm going to come back in a minute or two and i'll see what questions i can answer but just while you're typing out your questions let me address one thing that i think will come up which is what's next for blazer okay so blazer webassembly has shipped blazer server has been shipped for a while so what on earth does the blazer team spend its time doing these days well the answer is we are already hard at work building blazer internet five so the next preview release of dot net five or or whenever it does come out the preview sixth release will include blazer web assembly again so we've we've finally got blazer webassembly onto the mainline.net 5 track now and then once that's in we're going to be working on a bunch of improvements that have been long requested i think the highest priority one of all is stuff to do with performance and that's both build time performance and runtime performance that is a big focus of the team and we'll be looking to find ways of creating some pretty big gains in that during net five there are also some programming model improvements that we have lined up inside the component apis that have been long requested by the community such as the ability to add type constraints and require parameters and things like that which you may know about if you're already inside the blazer community another highly requested feature is css isolation uh which we are working on at the moment we've also got some web assembly specific improvements that we're looking at uh we are still exactly figuring out how much of this is really possible to achieve on the time that we've got so there's no specific promises here but we're looking at things like the ability to do true simultaneous multi-threading which is not something you can normally do in javascript but the web assembly runtimes give us the ability to do that and the ability to load parts of your application incrementally or as some people call it lazy loading okay so that's all i've got for pre-prepared content if you want to get started and i hope you do then the best place to start is blazer.net which gives you all the information you need to get started on whichever platform you prefer to do your coding on and if you want the code from this talk the car checker example app then you can go to the url that you can see here aks.ms blazer dash car checker and you will get to a git repo which includes the source code for the application so you can try it out and dig into it a bit more yourself okay so we have got a few minutes that i tried to leave at the end where i can hopefully answer the questions uh we'll see and i am going to have a look at that now so someone is saying aaron is saying how easy is it to write a wrapper for an existing javascript library if it's not already available well the answer is it depends on whether the javascript library has a nice api to interact with or not but as long as it does then you can make calls into javascript using the js interop apis which you can see the example that i showed you before which was in local vehicle store so you can see that this is an example of making a call into javascript you can deal with passing arbitrary data which gets json serialized or receive arbitrary json serialized data you can call asynchronous methods uh you can have javascript call your.net code including asynchronous methods and that all works out okay if you want an example of this done then you could if you want to go to what is it called something like blazer um let's see get actually i'll post a link into the chat later on when i find it of a nice example of a package that wraps up some um javascript interrupt code okay so uh atomos is asking can you use message format with localizer yes you can an example of that would be here when we are localizing this welcome message we say welcome and then we can inject sub strings into that such as the user's first name i hope that answers that um let's see rhiann is saying does the localizer work velocity works with resets files can we integrate it with a third-party tool the answer is as long as your third-party tool is based on getting stuff from satellite assemblies then yes that should just work by default but how well it works is simply going to be a question of how well this third-party system is able to run on a net standard environment like blazer webassembly uh the question is the pwa support released yes it's very much released it was not delayed i don't know where that rumor came from okay any other questions looks like maybe all the questions are answered so get your questions in quickly if you do have any more otherwise i'm going to be signing off and giving you a bit of time to go and try out blazer webassembly yourself uh is there any obfuscation in.net for webassembly well microsoft doesn't get any obfuscation tools so there's nothing built in with blazer or any other.net technology but third-party tools do exist and since inside the browser we're just running.net assemblies regular.net assemblies they don't have to be translated into webassembly then any third-party obfuscator should work as long as it doesn't do anything that's so weird that it's not really even compatible with net anymore any limitations on integrating third party.net business logic the limitation is that blazer web assembly runs on net standard 2.1 so as long as your business logic package targets net standard 2 1 or below then it should work absolutely fine there are some exceptions to which apis are supported because of course your code is still running inside a browser sandbox so you can't do things like directly read and write files from the local file system you can't mess around with the user's windows registry or things like that because of course the browser sandbox does not have any way of permitting that but for any part of net standard that makes sense in a browser it should work and for things like business logic as long as it's just logic and it doesn't for example directly talk to a sql database then you should be able to find that that works absolutely fine what's the coolest use of blazer that you've seen before uh i don't know i'll have to think about that i don't want to unfairly ignore people's school projects so i'll think about that and maybe respond in chat later on and i think i might wind this up now unless anyone gets a question in really quick give you another few seconds christopher myhill bristol on there great talk cool all right thanks everyone i think we'll call that uh done for the questions now we're just coming up to the end of the talk so let's say that we're all done there for any more questions you can post to me on slack or probably better still would be going to the github repo and filing issues or going to the blazer getter channel so that'll do for now i'm going to sign off i hope you have a superb rest of conference thank you everybody
Info
Channel: NDC Conferences
Views: 44,806
Rating: undefined out of 5
Keywords: blazor, asp.net, steve sanderson, asp.net core, webassembly
Id: kLhoRyLxwAE
Channel Id: undefined
Length: 56min 18sec (3378 seconds)
Published: Mon Aug 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.