 Up next, App Services, every.NET developer needs to know with Tim Heuer and Angelos Petropoulos. Did I say it right? Perfect. Off we go. Awesome. Thanks everybody. Good morning, good evening, good afternoon wherever you're watching from. I'm Tim. This is my esteemed colleague Angelos. We're here to talk to you about Azure services that every.NET developer should know and get excited about using your apps. So first, I want to set the stage Angelos, and just make sure everybody, we're going to throw out some terms about Azure. So we should probably make sure everyone knows what those terms are. In Azure, there's a lot of different things that we'll talk about, but just a level set. So we're going to say things like accounts and subscriptions, and accounts is something that represents you and me, our actual identities. That's how we authenticate with the service. A subscription is something that we can share together. That's a billable unit. You'll also hear us talk throughout this session about resources and resource groups. A resource represents an individual unit of any service that's created in Azure. So like I have an app service, which is one of the things we'll talk about today, is an actual resource. A resource group is things that we can group together, perform some more security on, establish some more boundaries of what can be in those services and configuration around there. So we'll talk about those two things quite a bit. Most explicitly, today, we're going to talk about two things, right, Angelos? We're going to talk about hosting and services, right? In the way that we think about these things is, hosting is you're going to provide the code and Azure is going to run it for you. The services that we're going to talk about is more, you're going to provide the data and Azure's services are going to take some action on the data. So specifically during this session, we're going to focus on those two aspects of hosting and service. To do that, Angelos has built a very simple application to allow us to walk through that. So we're going to show an image gallery, right? And so- It's worth millions. It's worth millions. Yeah, we are going to IPO at the end of this. You'll want to get in at the bottom here. So I think we should just dive right in and get started. So throughout this, we're going to cover roughly five services that are really table stakes that .NET Core developers should want to know. Everybody should be aware. Yeah. So tell us about this site and show us the first demo here. Let's jump straight in because we have a lot to cover. So I have the simple ASP. .NET Core MVC application working here, already running locally, local host. It's called Core Image Gallery. I can register a new user and log in. So I'm going to go ahead and log in with my demo account. So as you're logging in, yeah, so what are you using for this authentication here? Yeah, this is powered by ASP.NET Core Identity. So go search for that if you want to know more about it, but the whole register with different accounts, social, and all of that comes kind of for free and you basically configure it and it just works. And it's all taken care of for you when you do the initial configuration, right? That's right. So now I've logged in. I'm going to click Upload Image. I can pick one from my local machine to upload it to our gallery. It's going to take a little while to upload it. It's telling me it did some file processing and the file will be available shortly in the gallery. And I can just click Return to Gallery. And here's the picture I uploaded. And I'll open it up to show you that the processing we were talking about is just a little, whatever my case. Copyright so that we protect our millions. Yeah, nobody will steal this now. All right, so very simple application. Let me stop it from working. Let's go back to the code and check out what I just showed you. Simple solution, a couple of projects. I'll start with image gallery.model, nothing but a class library. Nothing interesting here, really just a class with some properties. That's what we use in the page that shows you the confirmation after the upload. So just showing you there's no tricks. So nothing really interesting there. The main project, ASP.NET Core MVC. I'll show you, start up the CS world quickly. Classic stuff, like we said, we're using ASP.NET Core Identity. We're using MVC. But the thing I want to draw your attention to is we have a service, an interface called iStoreAtService. And an implementation of it with fileStoreAtService. So let's start with the interface. Let's check that out. It's pretty simple. Just a couple of operations on it, getImagesAsync. That's so we can populate the gallery. And addImageAsync is just when you do another upload. So nothing too crazy here, close that down. Actually, I wanted to show you the implementation as well. Yeah, the one we're currently using. Yeah, so let's go and take a look at the class that implements iStoreAtService. And this is giving away the secrets immediately. You'll see here there's going to be a folder called userImages. We're going to put it under www root. And that's where all the pictures we upload go into. It's the local store for the server. Nothing really interesting in the constructor. AddImageAsync, I have a little helper method here to get some properties out of the image so I can show the confirmation page later. We just get the path here for the destination. We create a stream. We use a little watermarking class to add the watermark. I'll just show you that real quick just curious. I don't really know what it's doing but it works. All right. And then finally, we just record the upload and you get to see the screen that says go back to the gallery. So it's a standard ASP.NET Core web application, uses MVC. Yeah. Nothing special that's any cloud specific or binding us to any decisions at this point. So let's- But now we've only been running at local. Yeah, this is all local and I forgot to mention that ASP.NET Core Identity uses local DB. So we have a dependency on SQL server right now, but yeah. It's a local instance of it. That's right. So let's take this application which is a typical application and it's deployed to Azure and then slowly we'll try to modernize it and make it a bit more cloud native. Let's do it. All right, so I'm going to right click on the project and I'm going to click publish. Now the one thing that we've already done is we've already created that account in subscription that we talked about. Yeah, it's because we don't want to waste too much time now in the demo. That's pretty easy to look up and you can do via the CLI through the portal. It's all pretty easy here. So here when I right click published, I'm picking Azure App Service and because you're nice and you've already provisioned the resources for me, I'm just going to select existing and go find them. I try to add value by provisioning resource groups all day. That's fantastic. Yeah. So here it's going to access my subscription and then it's going to go look for all the resource groups under that subscription and then I will be able to find app service instances running in those resource groups. So like you said, a resource group is just a folder. It's basically a nice way to organize your stuff so you can go find it easily. You can have more than one subscription and in fact, that's what took it a little bit long because you do have a lot of subscriptions. Seven, sorry. Yeah. All right. So here's my demo resource group and I'm picking my existing instance of app service. I'm clicking okay. Now Visual Studio will talk to that instance, captures some information and all I have to do now is hit publish. But before I do that, I have to make sure my ASP.net core identity data and schema makes it up to the new instance of SQL Server you've created for me. Right. Because we were using the local DB. Right. And now we want to use an Azure SQL provider in fact Azure SQL itself. But you did all the provisioning. So I'm not really sure what you did there, but thankfully Visual Studio will let me do everything through its options. So if I just edit the publish profile so I can access settings, you will see here at the bottom of the dialogue, we're discovering data contexts. What that means is Visual Studio is now hitting the app service instance up selected and it's asking it if it has any SQL Server connection strings. Because if you've already done the work, I might as well benefit from it. Yeah. So now that the spinner is done. And it's real time. This is real time. This is real time. Yeah. This is communicating with our subscription and I've already done the provisioning of Azure SQL for you and provided a connection string for you. So why should I bother with that again? Right. Yeah. All that is there. I can just pick it, check a box, that will apply entity framework, data migrations as soon as I publish. So all I have to do is save, hit publish. Now what's going to happen is Visual Studio, of course, will build a project. We'll talk to the app service instance, upload all of the content, then it's going to go and check SQL Server, run entity framework migrations. And we try to give you visual clues what's going on. You can always go to the output window and get more verbose information about what's happening here. So why are we using app service and not a VM? Right. So VMs are great. In fact, if you go and create a VM through the Azure portal, we even have a very nice template where it will set up IIS, NMS Deploy, and then you can just come into Visual Studio like I did now, right-click, publish to the VM. It's all great. But this is a talk about, you know, services of Azure that you should know about. And app service should really be your go-to hosting option in Azure. At the very least, you're getting a fully managed instance, so you don't have to worry about patches and security fixes and frameworks and all that kind of stuff. It can very easily scale out and scale back based on just setting some metrics and some options up. It can make sure that you can keep your site running, even when you're deploying into the same instance by taking advantage of a feature called deployment slots. Like a staging and production. There's many, many good reasons. It's your go-to. And don't be all these features, if you don't necessarily need them, don't think that it's superfluous. There is different cues and tiers, so there is different pricing and features for DevTest than production. So maybe you don't need everything all at once. And I think one thing that I like about app services, which you mentioned is, you know, VMs are great, but there's still some configuration you have to do to kind of bootstrap them. Whereas app service, as we just saw, you know, deploying even directly from an IDE or from DevOps, you know, it's taking care of a lot of that configuration for us. We know, we're just telling it, hey, we have a .NET Core framework and here's my bits. Right. Yeah. So we deployed. Look, the URL doesn't say local host anymore. Right. So this is live. Success. Running in Azure right now. Awesome. Fantastic. Yeah. So let's go back to the slides real quick and just kind of review those first two things. So we said we're going to cover, hopefully cover five services here. The first two things we just were able to show is talking about two services, App Service, which kind of is that hosting platform here. App Service is really great for web apps and APIs. As Angelos mentioned, it's a fully managed environment. So you get the OS patching, high availability and high scale by default, with you able to kind of provide the throttling mechanisms as well within that. And it's first class tooling across Visual Studio family of products as well as you saw. Here we're using Visual Studio for Windows, but we also have similar experiences in VS for Mac and code. And then the second thing, because we were using ASP.NET's identity integration, we were using a local DB SQL Server instance. And so we were able to use any framework migration scripts to put that into Azure SQL. So now our app that was running on-prem, basically prem being your box here, is now hosted in Azure and our identity is also in Azure. But we've got a couple more bits there, right? So we were uploading images. Were those images in SQL? No. Okay, let's take care of that. Yeah. That's probably bad. So yeah, the app is running in Azure, but we can do a bit better because if we wanna take advantage of app service and its ability to scale out, for example, you will notice or you'll remember that the images are being stored under WWRoot. Yeah, the file storage provider that you had there. Right. So a new instance is provisioned, then the folder will be empty. If traffic goes to that server, the gallery will look empty. Yeah, RedX. We don't like RedX images. No. All right, let's solve that. So we can go back to the demo. All right. So what I'm gonna do here is I'm gonna introduce the third Azure service called Azure Storage. Basically, we wanna be able to store files. It's a common thing apps have to do. Azure has a service for it. So what I'm gonna go do here is show you a new implementation of iStorageService, the same interface we saw before. Some simple strings and variables here. We'll talk about those. There's nothing to worry about, but let's go back to the addImageAsync and compare it to the previous one. So here we have getImageProperties like before. We have an upload container and we just get a reference to it. This is basically a stream we can write into. We then create a memory stream before we were creating a file stream because we're writing locally here. I wanna do the watermarking. So I'm gonna do it in memory. And then imageBlob, which is a reference to Azure Storage. We're just gonna copy the stream into it and now the picture is uploaded. Now those two APIs that you're calling there, the getBlockWob reference and the upload from stream. Those aren't things that you wrote, right? No, no, that's Azure. That's a library that I get for free. And so because we're making the decision, we're using Azure Storage and Blob Storage in this case. We have an SDK available to us that allows us as .NET developers and C-Sharpa developers in this case to work in the language we love, get all the productivity and visual studio that we like and have kind of this strongly typed interface with the service, not have to worry about rest and all that type of thing. Perfect. So now what I have here is the app will work just as before but now it's gonna take the pictures and upload them into storage. So even if new instances are fired up, then they will just talk to the same instance of storage so I'm good, but we can do even better. When you're in the cloud and you're migrating applications, it's a great opportunity to optimize and get efficiencies and modernize an application. And when you're on-prem, this typically tasks like things firing off on timers and scheduled events and triggers that trigger workflows and multiple operations. And typically those things are achieved with let's say a window service running somewhere or Linux. Some DNN or Chrome job or something like that. But how do you do that in app service? You can't really do whatever you want on that box. So Azure offers you a service called Azure Functions which I'm gonna use now to take the watermarking process out of the main app and just do the watermarking after the picture has been put into storage with some sort of background task. Great, so we're identified an area where it's not mission critical to us. Exactly. As someone's uploading and we're kind of almost like async workflow in nature to offload this little microservice that you're gonna create here. Yeah, I mean, it doesn't really matter if the image takes a second or two to get what I'm asking. We may lose $1 in our IPL. Well, I think we'll get that $909,000. Okay. It's good, we're good. What we lose we'll make up for in savings on Azure, they tell me. All right, so back on the project. So I have a new project here in my solution called imageGallery.azfunctions. How did I get this in here? I did right click, add new project and I picked Azure Functions because I had picked it before or I can just search for Azure Functions up here and I create the project. Now inside it, I have my watermarker class from before. I just moved it over here. It's the same code. Same code now. I still don't know what it does. Image uploaded. So that's my first Azure Function. I'm gonna right click and I'm gonna show you how I did that. I click add, new Azure Function. You get to name it, whatever you like. You click add. And here's where I talked before about, you probably wanna have some sort of trigger or timer. So here we have the list of possible ways you can execute your Azure Function. Very commonly you have HTTP triggers. Maybe you do something on the website and the website calls a function. This is like get and post and click actions here. But I also have what I want here to use in this case which is the blob trigger. So as soon as the picture gets uploaded to blob storage, I'm gonna get told that just happened. So I just gave you the connection string and that's how I got it in there. So let's take a look at the code. There's not a lot to it. I have my watermark up here. I have an attribute telling me that this is actually gonna be a Azure Function and the name can be whatever I wanted. It can be different than the name of the method. And I'm gonna look at my first parameter called input blob. That's basically whenever the picture gets uploaded because the annotation says it's a blob trigger, exactly. The name of the container is gonna be called images. And then whatever the file name is, it's gonna go into this variable called name. So I have a string name here and I can reference it conveniently through here. And then I have a second variable parameter which is basically my output. So after I do my watermarking, I'm gonna put the contents in here and it's gonna get written where? Into a new folder container called images-watermark. And that's also an Azure storage blob container. Yeah, in the blob container, you can create as many of these groups as you like. Got it. So all this will do is be notified, do the watermark and then move the picture. But since I'm creating these two groups and I'm moving pictures from one to the other, what I wanna do is also clean up after myself. So I wanna go and delete the original image that was uploaded. So what I'm gonna do is go to delete original image. That's just another Azure function. Again, with a blob trigger. So keep in mind you can have more than one per project. Sometimes it's often easy to miss. More than one, more than one function per project, yeah. And here what I'm doing is I'm showing you that you can even access configuration values in the definition. Ah, so before where we had kinda, you had the hard-coded blob name. Now you're pulling it from ASP.NET config. Exactly, so just showing you that both are possible. The other one was just easier to read. So here what we're gonna do is we're gonna be told when the image lands inside the watermark container. So that's after the first function has worked. And what I'm gonna do is I'm gonna know to go and delete the original one now, all right? So I have this working and I think it's gonna work, but I wanna make sure it works locally before I put it into Azure. And even though I'm using Azure functions, something that is native to Azure, I can still run my project locally, including Azure Storage. What I have to do is fire off the Azure Storage emulator. This is a good point. So this is another set of tools that are allowing you to do cloud development, but have a faster inner loop development, you know, F5 debug kind of life cycle. And the emulator, you have to start it on your own because it's kinda really hard for Visual Studio to know exactly when you're gonna access it and by then it might be too late. But for Azure functions, all I have to do is right click, set it as the startup project, and we're gonna put a break point, see what happens. So we've started the storage emulator and now you're starting the Azure function. This is gonna run on the cloud now or this is also another emulator. This is now the emulator being fired up by Visual Studio because it's clever enough to know that's exactly what you need. And so this is a local instance of the Azure functions runtime that's running. That's right. And you'll notice this is the 64 bit which we added support for recently. Nice. So VS has detected the runtime is up. It deployed my function and acquired the log to it. And now the function should be working. Now, two ways to contest this. So now the function's there, it's ready to listen. It's, yeah, it's ready to do the work. Ready for the trigger. All right, ready for the trigger, okay. And since we're on the topic of working locally, I also wanted to show you the Azure Storage Explorer. That's a kind of cross platform app that you can download separately. Similar functionality exists in VS if you go to Cloud Explorer, so look that up. But Azure Storage Explorer lets me interact with Azure Storage, whether the instance is in the cloud or locally. So here I can actually go and look at my storage account locally. I can look at my emulator running. I can look at my blob containers. And I can actually see the two containers I had before images and images watermarked. So if I really wanted to execute my Azure function locally, I can literally just drag drop file using this tool and it's gonna kick it off. But let's do the full thing. I'm gonna come back to Visual Studio and I'm gonna fire up the website. And now we're gonna run the app itself. Yeah, I'm gonna run that locally and just exercise the full end to end. So now what we have here as this is spinning up, we're running our local process that's using the storage SDKs, using serverless functions, but running both of those basically in a local interloop. That's exactly right. We haven't published anything to our Azure yet. Everything is local right now, local host. So I'm gonna do the same thing now. Upload an image, pick a different one this time. So file is being processed, blah, blah, blah. It will be available so, oh. And that's our break point. Break point here. All right, so that if I go here, put a break point on my delete one. If I go back to upload, I'll just let it go. Come back to my website. Oh, didn't have enough chance. My second trigger has fired off. Everything is happening synchronously. All right, it's all good. I'm gonna continue this. Now when I'm gonna hit return to gallery, the image will already be there and it's already watermarked. That's awesome. So now we can go ahead and republish these, republish our app to Azure at that point. Exactly. So what I want you to see here is if I wanna take this Azure function and publish it to the cloud, right click, publish. Exactly the same experience as before. I already had a profile there. Create, select existing. Same configuration. The same as before. Not gonna bore you with the same stuff. Awesome. So now we've got, we're using app service to host, Azure SQL in the cloud, blob storage for our files, and serverless for some lightweight functions that kind of asynchronous in nature. We've got like four services we're running on top of the app itself. So how are we gonna feel good about the health of the app here? Okay, so feedback we get from customers a lot is running things in the cloud feels like maybe they're far away from the diagnostics a little bit. That's not true. That's not true. All right, so let's go back. Close all this down. I don't need anything local running. I'm gonna go to my production cluster now. I'm gonna go to my production resource group. So this is my website running in production right now. And I have a report that if you try to upload an image without logging in first, something happens to the app. So let's go check it out. I will go and upload the image. Pick one. Scotland. That one. All right. So we've got a crash here effective. This is the dreaded something went wrong but you're not in a development mode and you can't really get the call stack and now you're probably gonna be worried about, well, how do I get access to logs? And this is annoying. It was so much nicer when I was local. Well, let me just show you something called Azure Monitor. So now where we're going is we're logging into the portal. I'm gonna go back to the portal and you know how we said that resource groups are a nice way to organize your resources. What I'm gonna go do here is I'm gonna go to my resource groups, scroll down until I find my production resource group. And here I get a list of all the services this resource group has provisioned and you were kind enough when you provisioned our app service instance to actually attach it to Azure Monitor. What you get by just attaching it to Azure Monitor is diagnostics. So all I'm doing is navigating to the instance and oh look, there is a chart there for failed requests. Well, that's exactly what I needed. So I'm gonna click that. See where it takes me. Okay, so there's an action post upload. Yep, that sounds like what I just did. And it lets me drill into it because I'm gonna keep clicking until I get to a call stack here. Yeah, so we're able to go to the portal now and see, this is almost real time diagnostics as well of what happened. I just did it. And get basically to our core exception here. So this has an end to end transaction. It has automatically recorded for me without me doing anything special. If I keep going, I will eventually get to the call stack. This is what we all wanted to see. And we can figure out the exception there at this point. All right, so this says core image gallery extensions upload. Okay, so I wrote the app. We'd like somebody to do something without authorization. Yeah, I mean it's kind of obvious. I shouldn't let you upload a picture without sending in first. But the point was getting to the call stack, right? So now I can go back to my code and see that get image properties is assuming I'm authenticated basically. That's awesome. So let's go back to the slides and review that what we've seen here. So what Angelus was able to show is we had a typical ASP.NET core application, fairly simple one at this point, that was doing a couple different things. And we basically moved it all to the cloud, not having to worry about managing our own box and infrastructure. We got hosting out of app service. We've got data storage in two ways actually using Azure SQL, which if we needed relational database needs on top of our identity we could still use that as well. We're using blob storage as kind of our durable storage for objects and things like that. A serverless function that is just kind of asynchronous. And actually by the way, we only pay for that when we call it. That's right. So it's not this long running process. And then we have really rich insights in monitoring into our app. So there's a ton more in Azure that we could do as well. We didn't even talk about containers and things but that's kind of like the next level that I think an enterprise application might look at is how do we do container orchestration and Azure has Kubernetes services that we can do there. As well as other services that, there's data services with Cosmos DB, Active Directory, another service bus and SQL managed instance and everything like that. So I think it's a really quick overview of kind of some key services that .NET developers should know. Here's some resources for you. We want you to kind of go get the tools and SDKs.NET Core 3 release, getting Visual Studio and both the core SDK. And then as well that second link if you want to learn more about Azure and actually walk through some of the same tutorials of the services and get those SDKs that make it easier for a .NET developer, that's the place to go. And if you haven't tried Azure yet, you can get a free subscription that gives you free services, some forever and some for a 12 month period. I think the good thing about the, we didn't, there's a lot more richness in the monitoring and diagnostics. And I think a good thing is the session right after this, Sarabha is going to go over some more of what we've done more in .NET Core 3 and for those type of things. So thanks, Angelosa. It was good, good primer and encourage everyone to take a look at this. Mika. All right. Thank you, Tim and Angelos. So as you don't know, Tim is actually my boss. So how are you doing, Tim? I'm doing well. You're doing a fantastic job. Thank you. So yeah, we have a few questions that we can go over right now. Let's see. This one's for Tim. Good to see Tim presenting. Brings back Buttersweet memories of Silverlight. Do you have anything to say about that? Probably not allowed to say anything. Let's see the next one. Can App Services run Blazor? Can App Service? Yes, and if you're into Blazor and into App Service, also check out the Azure Signal R service. If you need more info, let me know. Yeah, Dan Roth gave two presentations earlier today, but also yesterday, kind of how that kind of all works together as well with Blazor. Okay, awesome. Here's another one. This one's from John. Will VS generate the EF scripts if you just saved the published profile instead of clicking publish? Clicking publish actually deploys the app and then executes the migration scripts I had already set up before. So I just didn't type, you know, create migration, but you have to do that first, and then publish will execute it for you. So creating the profile doesn't create a migration script for you? It does on the server, yeah, yeah, yeah. But locally it doesn't. Yeah, locally, yeah.