MVC 6 install as a Windows Service (ASP.NET Core 1.0.0) - asp.net-core

UPDATE - 26th July 2016
I have added the solution to this in ASP.NET Core 1.0.0 in the answers below.
I have created a simple MVC 6 app and have included the Microsoft.AspNet.WebListener library so I can host outside of IIS.
From project.json:
"dependencies": {
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta4",
"Microsoft.AspNet.Mvc": "6.0.0-beta4"
},
"commands": {
"web": "Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.WebListener --server.urls http://localhost:5000"
}
When I publish this I can run the web.cmd file and get the site running in a console window. Great!
But in OWIN you can use TopShelf to launch your web app from a Console Application. This can then be built as an executable and installed as a Windows Service.
Is there a way to do this with an ASP.NET 5 MVC 6 web app?

You can run a DNX app as a Windows service, however, you can't run the CMD file directly. You will get an error saying the following: 'The service did not respond to the start or control request in a timely fashion.' You can point directly to dnx.exe and pass the project folder and command as arguments.
Read this post for a lot more detail: http://taskmatics.com/blog/run-dnx-applications-windows-service/
Once you have your app set up. You can bootstrap ASP.NET from the OnStart method of the service. To do this you can use WebHostBuilder from Microsoft.AspNet.Hosting.
Lastly, you can ensure the app is still runnable in VS by passing an argument (such as 'non-service') to the Main method and check that before calling ServiceBase.Run, and if present, you can call OnStart directly instead. The project's properties gives you the option to pass arguments when running in VS.
UPDATE:
There is a follow up post which builds upon the one above. It shows how to run ASP.NET 5 with static files and MVC 6 in a Windows service. The link is here: http://taskmatics.com/blog/host-asp-net-in-a-windows-service/

As of the latest ASP.NET Core Version 1.0.0 libraries this is now somewhat simplified.
There is an open discussion on this topic on the ASP.NET GitHub page.
All ASP.NET Core applications are now Console Applications and there is a new library to host as a Windows Service that runs on the full .NET framework (which makes sense as this whole problem assumes a Windows web server).
We need to create a new ASP.NET Core Web Application (.NET Framework)
Check the project.json file to ensure that the "frameworks" section is as below:
"frameworks": {
"net461": {}
},
We need to then add the service hosting library Microsoft.AspNetCore.Hosting.WindowsServices and save the project.json to restore the package.
We then need to edit the program.cs file and add paths for running in debug and running as a service, the code for this is as follows:
public static void Main(string[] args)
{
var isDebug = Debugger.IsAttached || ((IList)args).Contains("--debug");
string runPath;
if (isDebug)
runPath = Directory.GetCurrentDirectory();
else
{
var exePath = Process.GetCurrentProcess().MainModule.FileName;
runPath = Path.GetDirectoryName(exePath);
}
var host = new WebHostBuilder()
.UseKestrel()
.UseContentRoot(runPath)
.UseStartup<Startup>()
.Build();
if (isDebug)
host.Run();
else
host.RunAsService();
}
The .RunAsService() method is an extension method provided by the Microsoft.AspNetCore.Hosting.WindowsServices lib.
To install as a service you just need to run the following command from an Administrator command prompt:
SC Create <service-name> binPath= "[PublishOutputPath]\mvc6-example.exe"
Please clone and view the working version on my GitHub repository.
I hope this helps :)

UPDATE: It seems like there is going to be a Windows Service hosting option coming in with RC2. See this GitHub comment for more info and this answer.
I am afraid the answer is no for this. I have been looking into this as well and the best way to do this is to deploy your project into a known location on disk and have a Windows Service to spin up the process which calls the cmd file. This way, the Windows Service will only act as a watchdog.
I am hoping to get some blog posts and samples on this as I have been looking into this in terms of deployment. There is also an open discussion here: https://github.com/aspnet/Home/issues/465

It is worth looking at https://github.com/aspnet/Hosting/tree/dev/src/Microsoft.AspNet.Hosting.WindowsServices
It seems that ASP.NET team is working on native support for hosting ASP.NET MVC 6 applications within Windows Services.
Here is a simple ServiceBase hosting an ASP.NET MVC 6 app:
/// <summary>
/// Provides an implementation of a Windows service that hosts ASP.NET.
/// </summary>
public class WebApplicationService : ServiceBase
{
private IWebApplication _application;
private IDisposable _applicationShutdown;
private bool _stopRequestedByWindows;
/// <summary>
/// Creates an instance of <c>WebApplicationService</c> which hosts the specified web application.
/// </summary>
/// <param name="application">The web application to host in the Windows service.</param>
public WebApplicationService(IWebApplication application)
{
_application = application;
}
protected sealed override void OnStart(string[] args)
{
OnStarting(args);
_application
.Services
.GetRequiredService<IApplicationLifetime>()
.ApplicationStopped
.Register(() =>
{
if (!_stopRequestedByWindows)
{
Stop();
}
});
_applicationShutdown = _application.Start();
OnStarted();
}
protected sealed override void OnStop()
{
_stopRequestedByWindows = true;
OnStopping();
_applicationShutdown?.Dispose();
OnStopped();
}
}

Related

Azure Application Insight wrong shows URL in logs for ASP.NET Core 6 Web API application with API versioning

I have an ASP.NET Web API application running on .NET 4.8. In this app, I'm using standard Microsoft API versioning from Microsoft.AspNet.WebApi.Versioning and Microsoft.AspNet.WebApi.Versioning.ApiExplorer.
For instance:
[ApiVersionExtended(SupportedApiVersions.V9)]
[RoutePrefix("v{version:apiVersion}/telemetry")]
public sealed class TelemetryController : ApiController
{
where ApiVersionExtended - my filter. In Azure Application Insight requests to my API are shown with the correct version. For instance:
But after migration to .NET 6, I lost the correct version number in AI logs, for instance:
My code has several changes after migration to .NET 6
[ApiController]
[AllowAnonymous]
[ApiVersionExtended]
[Route("v{version:apiVersion}/telemetry")]
public sealed class TelemetryController : ApiController
{
[HttpGet("ipInfo")]
public async Task<IActionResult> GetIpInfoAsync(CancellationToken cancellationToken)
{
/* some code here */
}
}
I can't find the analog [RoutePrefix] attribute in .NET 6.
Might someone know what the reason for this issue is? And how I can fix it?
As suggested by #Peter Bons, this can be the issue with your existing Nuget Package.
The Nuget Package required to Implement API Versioning in .NET 6 Core Web API is Microsoft.AspNetCore.Mvc.Versioning
Install Microsoft.AspNetCore.Mvc.Versioning Nuget Package
In Program.cs add the below services
To add versioning for WebAPI
builder.Services.AddApiVersioning(opt =>
{
opt.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(2, 0);
opt.AssumeDefaultVersionWhenUnspecified = true;
opt.ReportApiVersions = true;
opt.ApiVersionReader = ApiVersionReader.Combine(new UrlSegmentApiVersionReader(),
new HeaderApiVersionReader("x-api-version"),
new MediaTypeApiVersionReader("x-api-version"));
});
To Add versioning with Swagger, add the below services
builder.Services.AddSwaggerGen(Options => Options.SwaggerDoc("v1", new OpenApiInfo { Title = "Audit Self Serve platform", Version = "v1" }));
Use MapToApiVersion attribute to assign each action to a distinct version
[MapToApiVersion("1.0")]
[HttpGet]
OutPut:

Can we Host ASP.NET SignalR v2.4.1 in an ASP.NETCORE App?

I have a situation where my codebase is stuck in .Net 4.7.2 for now but I need to push some notifications on a Website which is built on Asp.Core 2.2.
Across the system we use SignalR 2.4.1 but it is completely re-written in .Net Core.
I tried hosting it in the same app without success. Owin does not seem to be happy.
Has anyone had any success with it or has any suggestion?
There has to be a way for projects migrating from .Net to Core.
Thanks
Ok so after along night I got a solution to this issue.
First just to make my setup clear.
There is an API project targetting .Net 4.7.2 which is broadcasting some messages via a SignalR 2.4.1 Hub.
There are some other Asp.Net 4.7.2 Projects consuming those Hubs which are working fine.
And also there is a new website build in .Net Core but targetting 4.7.2 framework.
The solution I ended up is essentially hosting an OWIN pipeline within the AspCore Pipeline.
First I needed to install the following packages:
Microsoft.Owin
Microsoft.AspNetCore.Owin
I also added a new extension method for the Core IApplicationBuilder interface that sets up OWIN on the same pipeline:
public static class OwinExtensions
{
public static IApplicationBuilder UseOwinApp(this IApplicationBuilder app, Action<IAppBuilder> configuration)
{
return app.UseOwin(setup => setup(next =>
{
IAppBuilder owinApp = new AppBuilder();
var aspNetCoreLifetime = (IApplicationLifetime)app.ApplicationServices.GetService(typeof(IApplicationLifetime));
var owinAppProperties = new AppProperties(owinApp.Properties)
{
OnAppDisposing = aspNetCoreLifetime?.ApplicationStopping ?? CancellationToken.None,
DefaultApp = next
};
configuration(owinApp);
return owinApp.Build<Func<IDictionary<string, object>, Task>>();
}));
}
}
Then in the Startup class of the Core project, in the Configure method I was able to use my extension and register SignalR hubs to it like this:
Startup.cs
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
...
app.UseOwinApp(owinApp =>
{
owinApp.MapSignalR();
});
...
}
This way we can add more middlewares to the OWIN pipeline if we need to for whatever reasons.
I hope this helps.

Service not calling OnShutdown() when windows shuts down

I have .net core console application, which is hosted as windows service.
I want to catch an event if the user logs off/shutdown the computer.
I have found ways to catch this event in .net framework (here & here).
But I cant figure out how to achieve this in .net core.
To create service I am using "ServiceBase" class. Sample code is as given below:
public class MyService : ServiceBase
{
readonly string LogPath = "D:\\TestAppService.txt";
#region Constructors
public MyService()
{
this.CanShutdown = true;
}
#endregion
#region Protected Functions
protected override void OnStart(string[] args)
{
//your code here
// call the base class so it has a chance
// to perform any work it needs to
base.OnStart(args);
}
protected override void OnStop()
{
//your code here
// Call the base class
base.OnStop();
}
protected override void OnShutdown()
{
using (StreamWriter sw = File.AppendText(LogPath))
{
sw.WriteLine("shutdown == true");
}
//your code here
base.OnShutdown();
}
#endregion
}
The OnStop and OnStart methods are being called.
but when I shutdown the computer my OnShutdown method is not called.
According to aspisof.net, you should be able to use the SessionEnding API. This is because it is listed as being exposed in the windows Compatibility Pack - available on NuGet here.
This article on learn.microsoft.com shows how you can include it in a .NET Core application.
tl;dr
Add the NuGet package
Target Windows only
One thing to note: this was originally designed to be a temporary fix for porting Windows specific .NET code over to .NET Core.
The more accepted way to implement Windows only features is to move as much code to .NET Standard libraries as possible, and to use conditional compilation directives to include platform specific code when building for that platform.
By design dotnet core is not "friendly" with platform specific stuff
(like listening to log off event seems to me).
The solution I use in one of Windows-hosted services is described here.
When application domain is forced to close by operating system on shutdown - there is a room for using AppDomain event handlers.

Running ASP.Net Core Background Tasks after AppPool Recycling

I have an asp.net core application running on windows server. This is using some background tasks for using external service to get the data. We are facing an issue that after our app pool recycled/restarted, the background task is not running. This is running only after we are accessing the application. We found an article regarding this.
https://weblog.west-wind.com/posts/2013/Oct/02/Use-IIS-Application-Initialization-for-keeping-ASPNET-Apps-alive
Since this article describe asp.net application, below code will substitute the above solution in .net core application
public class Startup
{
public void Configure(IApplicationBuilder app)
{
var applicationLifetime = app.ApplicationServices.GetRequiredService<IApplicationLifetime>();
applicationLifetime.ApplicationStopping.Register(OnShutdown);
}
private void OnShutdown()
{
// Do your cleanup here
}
}
Is there any other work around to solve this issue?

monodroid wcf call

I'm having difficulties with accessing a WCF service. My service is
running in the same solution as the MonoDroid App and is hosted by visual
studio. I configured it as BasicHttp. The reference adds ok but at runtime
when I call the one simple test method, I get ;
System.Net.WebException
it's very simple this is web service
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
and here is call
button.Click += delegate
{
localhost.Service1 se = new localhost.Service1();
button.Text= se.HelloWorld();
};
and error snapshot in attachment
I agree that you need to add more information. However, I responded to this question sometime ago and this is what I am doing for the WCF stuff and it's working great for me.
Using Soap in Shared Mono Library for WP 7 and Android
This might help out.
One other thing that I just thought of. Do you have the internet option in the network manifest selected as shown here:
http://docs.xamarin.com/#api/deki/files/1026/=RequiredPermissionsVS.png