{"id":22110,"date":"2016-11-01T13:38:30","date_gmt":"2016-11-01T20:38:30","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/aspnet\/?p=22110"},"modified":"2016-11-01T13:38:30","modified_gmt":"2016-11-01T20:38:30","slug":"visual-studio-tools-for-azure-functions","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/dotnet\/visual-studio-tools-for-azure-functions\/","title":{"rendered":"Visual Studio Tools for Azure Functions"},"content":{"rendered":"<p><strong>Update 5-10-2017: The<a href=\"https:\/\/blogs.msdn.microsoft.com\/webdev\/2017\/05\/10\/azure-function-tools-for-visual-studio-2017\/\"> first release of Visual Studio 2017 Tools for Azure Functions<\/a> is now available to try.  As discussed in the Visual Studio 2017 Toolspost and these 2015 tools were preview tools that provided us great feedback and learning.  However, as outlined in our <a href=\"https:\/\/blogs.msdn.microsoft.com\/webdev\/2017\/04\/14\/azure-functions-tools-roadmap\/\">roadmap pos<\/a>t, the pivot to precompiled functions with a focus on .NET Standard 2.0 means we have no plans to release any further updates to 2015 at this time.  We would encourage everyone to try out the new tools for Visual Studio 2017.<\/strong><\/p>\n<p>Today we are pleased to announce a preview of tools for building <a href=\"https:\/\/azure.microsoft.com\/en-us\/services\/functions\/\">Azure Functions<\/a> for Visual Studio 2015. Azure Functions provide event-based serverless computing that make it easy to develop and scale your application, paying only for the resources your code consumes during execution. This preview offers the ability to create a function project in Visual Studio, add functions using <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-overview\">any supported language<\/a>, run them locally, and publish them to Azure. Additionally, C# functions support both local and remote debugging.<\/p>\n<p>In this post, I\u2019ll walk you through using the tools by creating a C# function, covering some important concepts along the way. Then, once we\u2019ve seen the tools in action I\u2019ll cover some known limitations we currently have.<\/p>\n<p>Also, please take a minute and <a href=\"http:\/\/landinghub.visualstudio.com\/webdevtools-0\">let us know who you are<\/a> so we can follow up and see how the tools are working.<\/p>\n<h2>Getting Started<\/h2>\n<p>Before we dive in, there are a few things to note:<\/p>\n<ul>\n<li>These tools are offered as a preview release and will have some rough spots and limitations<\/li>\n<li>They currently only work with Visual Studio 2015 Update 3 with \u201cMicrosoft Web Developer Tools\u201d installed<\/li>\n<li>You must have <a href=\"https:\/\/go.microsoft.com\/fwlink\/?LinkId=518003&amp;clcid=0x409\">Azure 2.9.6 .NET SDK<\/a> installed<\/li>\n<li><a href=\"https:\/\/aka.ms\/azfunctiontools\">Download and install Visual Studio Tools for Azure Functions<\/a><\/li>\n<\/ul>\n<p>For our sample function, we\u2019ll create a C# function that is triggered when a message is published into a storage Queue, reverses it, and stores both the original and reversed strings in Table storage.<\/p>\n<ul>\n<li>To create a function, go to:<\/li>\n<li>File -&gt; New Project<\/li>\n<li>Then select the \u201cCloud\u201d node under the \u201cVisual C#\u201d section and choose the \u201cAzure Functions (Preview) project type\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image755.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb632.png\" width=\"628\" height=\"207\" \/><\/a><\/li>\n<li>This will give us an empty function project. There are a few things to note about the structure of the project:\n<ul>\n<li><b>appsettings.json<\/b> is where we\u2019ll store configuration information such as connection strings\n<i>It is recommended that you exclude this file from source control so you don\u2019t check in your developer secrets.<\/i><\/li>\n<li><b>host.json <\/b><a href=\"https:\/\/github.com\/Azure\/azure-webjobs-sdk-script\/wiki\/host.json\">enables us to configure the behavior of the Azure Functions host<\/a>\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image756.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb633.png\" width=\"358\" height=\"134\" \/><\/a><\/li>\n<\/ul>\n<\/li>\n<li>For the purposes of this blog post, we\u2019ll add an entry that speeds up the queue polling interval from the default of once a minute to once a second by setting the \u201cmaxPollingInterval\u201d in the host.json (value is in ms)\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image757.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb634.png\" width=\"233\" height=\"53\" \/><\/a><\/li>\n<li>Next, we\u2019ll add a function to the project, by right clicking on the project in Solution Explorer, choose \u201cAdd\u201d and then \u201cNew Azure Function\u201d\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image758.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb635.png\" width=\"575\" height=\"289\" \/><\/a><\/li>\n<li>This will bring up the New Azure Function dialog which enables us to create a function using any language supported by Azure Functions\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image759.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb636.png\" width=\"475\" height=\"267\" \/><\/a><\/li>\n<li>For the purposes of this post we\u2019ll create a &#8220;QueueTrigger &#8211; C#&#8221; function, fill in the \u201cQueue name\u201d field, \u201cStorage account connection\u201d (this is the name of the key for the setting we\u2019ll store in \u201cappsettings.json\u201d), and the \u201cName\u201d of our function.  <em>Note: All function types except HTTP triggers require a storage connection or you will receive an error at run time<\/em>\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image760.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb637.png\" width=\"628\" height=\"436\" \/><\/a><\/li>\n<li>This will create a new folder in the project with the name of our function with the following key files:\n<ul>\n<li><b>function.json:<\/b> <a href=\"https:\/\/github.com\/Azure\/azure-webjobs-sdk-script\/wiki\/function.json\">contains the configuration data for the function<\/a> (including the information we specified as part of creating the new function)<\/li>\n<li><b>project.json (C#): <\/b>is where we\u2019ll specify any NuGet dependencies our function may have. <em>Note: <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-reference-csharp#importing-namespaces\">Azure functions automatically import some namespaces and assemblies<\/a> (e.g. Json.NET).<\/em><\/li>\n<li><b>run.csx: <\/b>this contains the body of the function that will be executed when triggered\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image761.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;margin: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb638.png\" width=\"228\" height=\"236\" \/><\/a><\/li>\n<\/ul>\n<\/li>\n<li>The last thing we need to do in order to hook up function to our storage Queue is provide the connecting string in the appsettings.json file (in this case by setting the value of \u201cAzureWebJobsStorage\u201d)\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image762.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb639.png\" width=\"628\" height=\"158\" \/><\/a><\/li>\n<li>Next we\u2019ll edit the \u201cfunction.json\u201d file to add two bindings, <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-bindings-storage-table#storage-table-input-binding\">one that gives us the ability to read from the table<\/a> we\u2019ll be pushing to, and <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-bindings-storage-table#storage-table-output-binding\">another that gives us the ability to write entries to the table<\/a>\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image763.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb640.png\" width=\"362\" height=\"423\" \/><\/a><\/li>\n<li>Finally, we\u2019ll write our function logic in the run.csx file\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image764.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb641.png\" width=\"554\" height=\"682\" \/><\/a><\/li>\n<li>Running the function locally works like any other project in Visual Studio, Ctrl + F5 starts it without debugging, and F5 (or the Start\/Play button on the toolbar) launches it with debugging. <em>Note: Debugging currently only works for C# functions. Let\u2019s hit F5 to debug the function.<\/em><\/li>\n<li>The first time we run the function, we\u2019ll be prompted to install the Azure Functions CLI (command line) tools. Click \u201cYes\u201d and wait for them to install, our function app is now running locally. We\u2019ll see a command prompt with some messages from the Azure Functions CLI pop up, if there were any compilation problems, this is where the messages would appear since functions are dynamically compiled by the CLI tools at runtime.\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image765.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb642.png\" width=\"429\" height=\"178\" \/><\/a><\/li>\n<li>We now need to manually trigger our function by pushing a message into the queue with <a href=\"http:\/\/storageexplorer.com\/\">Azure Storage Explorer<\/a>. This will cause the function to execute and hit our breakpoint in Visual Studio.\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image766.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb643.png\" width=\"557\" height=\"75\" \/><\/a><\/li>\n<\/ul>\n<h2>Publishing to Azure<\/h2>\n<ul>\n<li>Now that we\u2019ve tested the function locally, we\u2019re ready to publish our function to Azure. To do this right click on the project and choose \u201cPublish\u2026\u201d, then choose \u201cMicrosoft Azure App Service\u201d as the publish target\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image767.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb644.png\" width=\"483\" height=\"159\" \/><\/a><\/li>\n<li>Next, you can either pick an existing app, or create a new one. We\u2019ll create a new one by clicking the \u201cNew\u2026\u201d button on the right side of the dialog<\/li>\n<li>This will pop up the provisioning dialog that lets us choose or setup the Azure environment (we can customize the names or choose existing assets). These are:\n<ul>\n<li><b>Function App Name: <\/b>the name of the function app, this must be unique<\/li>\n<li><b>Subscription:<\/b> the Azure subscription to use<\/li>\n<li><b>Resource Group: <\/b>what resource group the to add the Function App to<\/li>\n<li><b>App Service Plan: <\/b>What app service plan you want to run the function on. For complete information <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/azure-functions\/functions-scale\">read about hosting plans<\/a>, but it\u2019s important to note that if you choose an existing App Service plan you will need to <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/app-service-web\/web-sites-configure#application-settings\">set the plan to \u201calways on\u201d<\/a> or your functions won\u2019t always trigger (Visual Studio automatically sets this if you create the plan from Visual Studio)<\/li>\n<\/ul>\n<\/li>\n<li>Now we\u2019re ready to provision (create) all of the assets in Azure. <em>Note: that the \u201cValidate Connection\u201d button does not work in this preview for Azure Functions <\/em>\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image768.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb645.png\" width=\"628\" height=\"468\" \/><\/a><\/li>\n<li>Once provisioning is complete, click \u201cPublish\u201d to publish the Function to Azure. We now have a publish profile which means all future publishes will skip the provisioning steps\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image769.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb646.png\" width=\"628\" height=\"418\" \/><\/a>\n<strong>Note:<\/strong> If you publish to a Consumption plan, there is currently a bug where new triggers that you define (other than HTTP) will not be registered in Azure, which can cause your functions not to trigger correctly. To work around this, open your Function App in the Azure portal and click the \u201cRefresh\u201d button on the lower left to fix the trigger registration. This bug with publish will be fixed on the Azure side soon.<\/li>\n<li>To verify our function is working correctly in Azure, we\u2019ll click the \u201cLogs\u201d button on the function\u2019s page, and then push a message into the Queue using Storage Explorer again. We should see a message that the function successfully processed the message\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image770.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb647.png\" width=\"623\" height=\"73\" \/><\/a><\/li>\n<li>The last thing to note, is that it is possible to remote debug a C# function running in Azure from Visual Studio. To do this:\n<ul>\n<li>Open <a href=\"https:\/\/docs.microsoft.com\/en-us\/azure\/vs-azure-tools-resources-managing-with-cloud-explorer\">Cloud Explorer<\/a><\/li>\n<li>Browse to the Function App<\/li>\n<li>Right click and choose \u201cAttach Debugger\u201d\n<a href=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image771.png\"><img decoding=\"async\" title=\"image\" style=\"padding-top: 0px;padding-left: 0px;padding-right: 0px;border: 0px\" border=\"0\" alt=\"image\" src=\"https:\/\/msdnshared.blob.core.windows.net\/media\/2016\/11\/image_thumb648.png\" width=\"328\" height=\"220\" \/><\/a><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>Known Limitations<\/h2>\n<p>As previously mentioned, this is the first preview of these tools, and we have several known limitations with them. They are as follow:<\/p>\n<ul>\n<li><b>IntelliSense:<\/b> IntelliSense support is limited, and available only for C#, and JavaScript by default. F#, Python, and PowerShell support is available if you have installed those optional components. It is also important to note that C# and F# IntelliSense is limited at this point to classes and methods defined in the same .csx\/.fsx file and a few system namespaces.<\/li>\n<li><b>Cannot add new files using \u201cAdd New Item\u201d: <\/b>Adding new files to your function (e.g. .csx or .json files) is not available through \u201cAdd New Item\u201d. The workaround is to add them using file explorer, the <a href=\"https:\/\/marketplace.visualstudio.com\/items?itemName=MadsKristensen.AddNewFile\">Add New File extension<\/a>, or another tool such as <a href=\"https:\/\/code.visualstudio.com\">Visual Studio Code<\/a>.<\/li>\n<li><strong>Function bindings generate incorrectly when creating a C# Image Resize function: <\/strong>The settings for the binding \u201cAzure Storage Blob out (imageSmall)\u201d are overridden by the settings for the binding \u201cAzure Storage Blob out (imageMedium)\u201d in the generated function.json. The workaround is to go to the generated function.json and manually edit the \u201cimageSmall\u201d binding.<\/li>\n<li><strong>Local deployment and web deploy packages are not supported:<\/strong> Currently, only Web Deploy to App Service is supported. If you try to use Local Deploy or a Web Deploy Package, you\u2019ll see the error \u201cGatherAllFilesToPublish does not exist in the project\u201d.<\/li>\n<li><strong>The Publish Preview shows all files in the project&#8217;s folder even if they are not part of the project: <\/strong>Publish preview does not function correctly, and will cause all files in the project folder to be picked up and and published.  Avoid using the Preview view.<\/li>\n<li><strong>The publish option \u201cRemove additional files at destination\u201d does not work correctly: <\/strong> The workaround is to remove these files manually by going to the Azure Functions Portal, Function App Settings -&gt; App Service Editor<\/li>\n<\/ul>\n<h2>Conclusion<\/h2>\n<p>Please <a href=\"https:\/\/aka.ms\/azfunctiontools\">download and try out this preview of Visual Studio Tools for Azure Functions<\/a> and <a href=\"http:\/\/landinghub.visualstudio.com\/webdevtools-0\">let us know who you are so we can follow up and see how they are working<\/a>. Additionally, please report any issues you encounter on our <a href=\"https:\/\/go.microsoft.com\/fwlink\/?linkid=836326\">GitHub repo<\/a> (include \u201cVisual Studio\u201d in the issue title) and provide any comments or questions you have below, or <a href=\"https:\/\/twitter.com\/AndrewBrianHall\">via Twitter<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Update 5-10-2017: The first release of Visual Studio 2017 Tools for Azure Functions is now available to try. As discussed in the Visual Studio 2017 Toolspost and these 2015 tools were preview tools that provided us great feedback and learning. However, as outlined in our roadmap post, the pivot to precompiled functions with a focus [&hellip;]<\/p>\n","protected":false},"author":404,"featured_media":58792,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[197,327],"tags":[],"class_list":["post-22110","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aspnet","category-azure"],"acf":[],"blog_post_summary":"<p>Update 5-10-2017: The first release of Visual Studio 2017 Tools for Azure Functions is now available to try. As discussed in the Visual Studio 2017 Toolspost and these 2015 tools were preview tools that provided us great feedback and learning. However, as outlined in our roadmap post, the pivot to precompiled functions with a focus [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/22110","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/users\/404"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/comments?post=22110"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/posts\/22110\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media\/58792"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/media?parent=22110"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/categories?post=22110"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/dotnet\/wp-json\/wp\/v2\/tags?post=22110"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}