Running ASP.NET Core 2 applications on Windows 10 IoT Core

It has been problematic to run ASP.NET Core applications on Windows 10 IoT Core as it is not officially supported scenario yet and many components we are used with are not built with Windows 10 ARM in mind. Still it easy to run web applications on Windows 10 IoT Core using ASP.NET Core 2. There are few tricks developers should know when building web applications for Windows 10 IoT Core. This blog post is short guide about ASP.NET Core 2 on Windows 10 IoT Core

Few things to mention before making hands dirty with real stuff:

  • ASP.NET Core on Windows 10 IoT Core is not officially supported scenario yet,
  • there is only .NET Core runtime available for Windows 10 on ARM but not SDK (yes, there is no dotnet restore and dotnet build etc available),
  • not all things that work on dev box will work on Windows 10 IoT Core and some of these things come out when trying to run web application on board.

With these warnings in mind let’s stat at safe waters and make default ASP.NET Core 2 web application run on Windows 10 IoT Core.

Building web application

I created default ASP.NET Core 2 web application with Visual Studio and made compiler build also .exe file that can be run directly. Just open project file and add output type setting. 

<PropertyGroup>
  <TargetFramework>netcoreapp2.0</TargetFramework>
  <OutputType>Exe</OutputType>
</PropertyGroup>

Now we can build web application just to find out that .exe file is not there. We will get it when publishing application.

Before building and deploying our web application to board we have to make it listen port 5000 on all interfaces. For this we modify porgam class and use * as host name.

public class Program
{
    public static void Main(string[] args)
    {
        BuildWebHost(args).Run();
    }

    public static IWebHost BuildWebHost(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseUrls("http://*:5000")
            .UseStartup<Startup>()
            .Build();
}

To deploy our application to Windows 10 IoT Core we need to publish it and tell dotnet utility that we want to support Windows 10 on ARM. This is done using the following command line.

    dotnet publish -r win-arm

If everything went well then published files are in folder bin\Debug\netcoreapp2.0\win-arm\publish.

ASP.NET Core 2 application published for Windows 10 IoT Core

Size of the publish folder in my case is 73 MB.

Deploying web application to Windows 10 IoT Core

To make simple test run for web application we need to deploy it to Windows 10 IoT Core. Expecting we have one set up and available here are steps to follow.

  1. Open PowerShell in Administration permissions and run the following command:

    Enter-PSSession -ComputerName minwinpc -Credential minwinpc\Administrator

    When logon dialog opens enter your Windows 10 IoT Core password.
     

  2. Create folder for web application and move to this folder:

    mkdir webapptest
    cd webapptest
     

  3. Open Windows Explorer and move to your board’s drive:
     
    \\minwinpc\c$

    Enter password when it is asked and then move to webapptest folder.
     

  4. Take files from web application publish folder and copy these to webapptest folder created before.
  5. Run the following command in PowerShell to open port 5000 of board:
     
    netsh advfirewall firewall add rule name=”ASP.NET Core Web Server port” dir=in action=allow protocol=TCP localport=5000
     
  6. Next, in PowerShell, run web application using .exe file:
     
    .\WebApplication6.exe

If there are no problematic dependencies in our web application then we can see some output to PowerShell window.

ASP.NET Core 2 application running on Windows 10 IoT Core

Notice that ASP.NET Core is listening to port 5000 on all network interfaces. Let’s open application now using browser.

ASP.NET Core 2 application running on Windows 10 IoT Core

We don’t see any debug output in PowerShell except exceptions if there are some.

NB! First request to web application is very slow but after this web application works fast and doesn’t put much load to board. Most of requests doesn’t consume much CPU and working set of memory is around 104 MB.

Running ASP.NET Core application at system startup

The final thing that caused some issues for me and other readers was getting ASP.NET Core 2 application automatically run when Raspberry boots up. I found excellent guide by Carlos Mendible that helped me out. The point is simple. We have to create DOS batch file to run PowerShell script that actually runs our web application. Batch => PowerShell => WebApplication. After creating these two files we have to register the batch file as scheduled task run once when system starts.

If you were in trouble with this and made experiments that didn’t succeed then please make sure you remove all previous scheduled tasks you created.

Wrapping up

Previously it was harder to make ASP.NET Core applications run on Windows 10 IoT Core but with ASP.NET Core 2 we can do it with less effort and hacking. All we had to do to make default web application run on Windows 10 IoT Core was to build it as executable and then publish it to board. It is still risky business as many things that run on usual boxes without any issues are not built with Windows on ARM in mind and issues with these components come usually out when running application on board. Still we can use ASP.NET Core on Windows 10 IoT Core and come out with solutions where simple web server on board is needed.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    19 thoughts on “Running ASP.NET Core 2 applications on Windows 10 IoT Core

    • Pingback:The Morning Brew - Chris Alcock » The Morning Brew #2483

    • December 14, 2017 at 2:35 am
      Permalink

      I followed the “Running ASP.NET Core 2 applications on Windows 10 IoT Core” by Gunnar Peipman.
      Raspberry Pi 3, Windows 10 IoT core 10.0.16299.19 , apart from a few problems of my own making, the default web page was up and running, next I’m planning to use this as a basis for a control interface.

    • December 14, 2017 at 10:35 pm
      Permalink

      This is something my next blog post will describe :) It’s actually the only option right now as ASP.NET Core 2 cannot be hosted in UWP background service. So, unfortunately there will be some inter-process communication. But still it’s possible to build great control panels for specialized devices.

    • December 22, 2017 at 11:47 am
      Permalink

      Hi, Very useful but is there a simple way to get it to run on startup?

      Paul

    • December 23, 2017 at 10:54 am
      Permalink

      Paul, this blog post may help you out: https://blog.falafel.com/windows-iot-core-powershell-on-startup/ I haven’t tried it yet but it’s one of few solutions I found.

      Darren, I was not able to host ASP.NET Core web server in UWP background task and it is also officially not supported scenario yet. I tried to make it work but with all attempts I ran into different troubles that come to issues that are out of my reach.

    • December 27, 2017 at 12:28 pm
      Permalink

      I tried to get it to run from a scheduled task (directly and with a script) and although the process did run, when I browsed to the website it did not serve up the pages although it did connect. I guess it’s an issue to do with user rights? Wonder if it’s possible to right a uwp application to host the exe?

    • December 27, 2017 at 1:11 pm
      Permalink

      I will try to find some time today to play with this issue. It’s probably something with permissions because under admin account web applications run well.

    • January 2, 2018 at 2:15 pm
      Permalink

      Thanks Gunnar got it running but did have an issue with it not starting after following the guide i guess it was the on boarding background task that was stopping it. the only other thing i changed was “startup” to uppercase just through force of habit.

    • April 29, 2018 at 4:12 pm
      Permalink

      When I launch my .net core app in powershell on rb3 then I get the error^

      .\AYPAW_API.exe : A JSON parsing exception occurred in [C:\Users\Public\AYPAW\AYPAW_API.runtimeconfig.json]: * Line 1,
      Column 2 Syntax error: Malformed token
      + CategoryInfo : NotSpecified: (A JSON parsing …Malformed token:String) [], RemoteException
      + FullyQualifiedErrorId : NativeCommandError

      Invalid runtimeconfig.json [C:\Users\Public\AYPAW\AYPAW_API.runtimeconfig.json]
      [C:\Users\Public\AYPAW\AYPAW_API.runtimeconfig.dev.json]

      This config looks like
      {
      “runtimeOptions”: {
      “configProperties”: {
      “System.GC.Server”: true
      }
      }
      }

      Could somebody explain me what I doing wrong?

    • July 22, 2018 at 6:51 pm
      Permalink

      Dear Gunnar,
      Have you ever try or, are you willing to try set up uwp app in windows 10 iot that use singalR CORE client and shoud connect and send data to ASP.NET CORE web app with signalR core hosted not on windows 10 iot but for example on pc in local network? I’am asking about it because I’m trying to do such think and when I lunch my uwp app on my pc (not on raspberrypi 3) every think works but when I lunch te same uwp app on windows iot 10 there is a HttpRequestExeption when I do
      await connection.StartAsync(); Any help? Any ideas?
      Bartłomiej

    • July 27, 2018 at 11:42 am
      Permalink

      So apparently it was problem with localhost, because I launch service on azure and now my signalR core client from windows 10 IOT is connecting to server on azure

    • August 9, 2018 at 2:09 pm
      Permalink

      Gunnar, this is a great post, Thank you.

      I am new to WebSockets but am using your code to help develop a web-based control panel for a RaspberryPi collecting temperature data. I have a background task on the Pi collecting data and now am using your Read and Report Tasks from your sample to communicate settings and data to the webApp also on the Pi. Can you suggest a way to determine some sort of identifier of the Clients? Perhaps in the WebSocketsMiddleWare point? I would like to have the background task stop sending data to the webSocketsWebApp if there are no clients to the WebApp other than the RaspberryPi itself. I had also considered using an AppServiceConnection between the two background tasks so that only the WebApp Service could send commands to the other local data collection background task. Thank you in advance for your advice.

    • October 2, 2018 at 1:46 pm
      Permalink

      Great article.

      I have been trying to sqlite db but ut fails.I am assuming that sqlite does not support arm compile? Do you recommend another db i could use?

    • January 22, 2019 at 6:32 pm
      Permalink

      Thanks for the nice article!

      I am using Windows 10 IOT Core v.10.0.17763.107 on Raspberry Pi 3 and my web application built with asp.net core 2.2! I was able to run my app successfully on the devices own web browser. But I was never managed to reach the web app from another computer at the local network!. I have used nearly 50 shades of the command:

      netsh advfirewall firewall add rule name=”ASP.NET Core Web Server port” dir=in action=allow protocol=TCP localport=5000

      with no success :( The firewall rule is added but each time I want to reach the app through network I get a timeout..

      Any idea?

      =====================================

      @Andrew Simpson : I was able to run asp.net core 2.2 using SQLite! For my case I had to use:

      dotnet publish -r win10-arm

      instead of abovementioned:

      dotnet publish -r win-arm

      to publish my app. And It was because the later one didn’t produce a e_sqlite3.dll into the publish directory.

      Hope it helps.

    • January 22, 2019 at 10:53 pm
      Permalink

      I found out what’s wrong. My app required that the BuildWebHost code block renamed to something else to be able to use SQLite so .UseUrls(“http://*:5000”) part wouldn’t work for me so adding it on the fly

      .\WebApplication6.exe –urls http:// *:5000

      fixed everything for me. I wanted to note here for the curious.

      A longer explanation can be found on: http://disq.us/p/1z5e82k

    Leave a Reply

    Your email address will not be published. Required fields are marked *