Writing Azure Functions with Rider
The first step is to install the plugin that will enable support for Azure Functions. Go to the Settings (ctrl+alt+s) > Plugins tab and search for "Azure Toolkit for Rider" and install it. I think it's a very popular plugin, or Jetbrains seriously wants to promote it, because it was the first plugin even when I hadn't installed it yet. Could be alphabetical too, not sure.
After a quick Rider restart, there is a new option in the Settings > Tools tab: "Azure". Select the Functions subsection, and install the latest version of the Azure Functions Core Tools. There is a link that will install the latest version automatically. Rider then downloads and installs or updates the Azure Functions Core Tools via NPM.
After another Rider restart (because restarting is what IT people do best), there is a new project template and several new class templates.
For this example, I create a Timer Trigger (because that will force me to set up the Azure Storage Emulator). This adds a class with the correct attributes and method signature for a timed Function. I looked up that the default CRON expression (
0 */5 * * * *) runs every 5 minutes. Code Hollow has a convenient cheat sheet, be sure to check that out if you are creating a custom schedule.
Now that the code seems OK, I want to run this little "hello world" program. The build stops me dead in my tracks, however.
The fix is not obvious, but fortunately, it's easy. In the projects .csproj file, the target framework is set to netcoreapp2.1 by default. This should be changed to netstandard2.0 (or whatever the latest and greatest version my dear reader is using). I know that at the time of writing dotnet core 3 just came out, but the template from Rider defaults to netcoreapp2.1, so I'm using the closest netstandard. There is either a little bug in the Rider template or there is something wrong with my setup.
<PropertyGroup> <TargetFramework>netstandard2.0</TargetFramework> </PropertyGroup>
Aah, a building Functions project. Now let's run it...
The next problem surfaces quite quickly. One of the debug outputs already warned me for it, but it becomes painfully clear that there is no AzureWebJobsStorage setup for local development.
The AzureWebJobStorage needs a local instance of the Azure Storage Emulator or an actual web storage endpoint. What was not immediately clear for me, is that the Azure Storage Emulator needs a SQL LocalDB instance. To get the LocalDB installer, download the SQL Express database. Select Download Media and in the next screen, select the LocalDB option.
The download location will open automatically. There will be an .msi installer to easily install the LocalDB database. I have accidentally installed SQL Server 2017 as well, which gave me problems while initialising the LocalDB. To circumvent those problems, install the latest Cumulative Update for SQL Server 2017. The problem was that the Azure Storage Explorer didn't work properly because it could not connect properly to the LocalDB. That prevented the Azure Storage explorer form creating a database with all the tables it needs. By the way, some articles told me to manually create the
AzureStorageEmulatorDb## database. That won't solve the problem, it will just mask the problem as the database won't have the necessary tables.
Once that's all done, verify that the LocalDB installed correctly by running this command
SQLLocalDB.exe i. It should print out
MSSQLLocalDB. Don't forget to start the database with the command
SqlLocalDB.exe s MSSQLLocalDB. Now, the Storage Emulator should work, right? Wrong!
There is no database with the specific name AzureStorageEmulatorDb59. I found this out after I tried starting the Storage Emulator and seeing that the initialisation of the emulator crashed. So, I tried running the command:
> AzureStorageEmulator.exe init Windows Azure Storage Emulator 184.108.40.206 command line tool Found SQL Instance (localdb)\\MSSQLLocalDB. Creating database AzureStorageEmulatorDb59 on SQL instance '(localdb)\\MSSQLLocalDB'. Cannot create database 'AzureStorageEmulatorDb59' : The database 'AzureStorageEmulatorDb59' does not exist. Supply a valid database name. To see available databases, use sys.databases.. One or more initialization actions have failed. Resolve these errors before attempting to run the storage emulator again. Error: Cannot create database 'AzureStorageEmulatorDb59' : The database 'AzureStorageEmulatorDb59' does not exist. Supply a valid database name. To see available databases, use sys.databases..
To remedy this, open SQL Server Management Studio, connect to the LocalDB instance and create a database with the name
See earlier remark about the Cumulative Update! That should prevent this error from happening. I'm keeping it in as I think others will run into the same problem.
AzureStorageEmulatorDb59. I tried doing this in Rider with the built in DataGrip tools, but I got an error. I've reported this, so it will get fixed in the future.
Now that the database is set up, I can finally start the storage emulator. All I have to do is fill in the
UseDevelopmentStorage=true. All set, lets run the function. Unfortunately, the output still complains that the
AzureWebJobsStorage still isn't filled in. After some checking in the config and the place where the function runs, it appears that the
local.settings.json file is not being copied. So, I change the
Copy to output directory setting in the file properties to
Copy Always. Now the Azure function starts up and a minute later, the breakpoint in my function is hit.
To make my life easier, I should add some "Before launch" external tools arguments in the Run/Debug Configuration so the LocalDB and Azure Storage Emulator start before each run. I think I'll set that up later.
Now everything is set up correctly. I can run and debug Azure Functions with Rider. It's not as transparent process as I'd hoped it would be, but it was a good learning experience for me.