Hosting ASP.NET Core in IIS without Kestrel - iis

Our hosting department is not willing to allow ASP.NET core hosting with Kestrel running or even installing the ASP.NET Core Server Hosting Bundle (AspNetCoreModule).
Is there any alternative to allow ASP.NET core in this situation?
Environment: Windows Server 2012 R2 with latest IIS and .NET 4.6.2.
It is a shared hosting environment and the application(s) must be running in IIS.

You can actually run ASP.NET Core in IIS within the worker process (thus not using the ASP.NET Core Module) by using OWIN.
This is possible due to the fact that ASP.NET Core can be hosted on an OWIN server and IIS can be made an OWIN Server.
Have a look at the following OWIN middleware which shows how to run ASP.NET Core on IIS. For a more complete example, see this gist: https://gist.github.com/oliverhanappi/3720641004576c90407eb3803490d1ce.
public class AspNetCoreOwinMiddleware<TAspNetCoreStartup> : OwinMiddleware, IServer
where TAspNetCoreStartup : class
{
private readonly IWebHost _webHost;
private Func<IOwinContext, Task> _appFunc;
IFeatureCollection IServer.Features { get; } = new FeatureCollection();
public AspNetCoreOwinMiddleware(OwinMiddleware next, IAppBuilder app)
: base(next)
{
var appProperties = new AppProperties(app.Properties);
if (appProperties.OnAppDisposing != default(CancellationToken))
appProperties.OnAppDisposing.Register(Dispose);
_webHost = new WebHostBuilder()
.ConfigureServices(s => s.AddSingleton<IServer>(this))
.UseStartup<TAspNetCoreStartup>()
.Build();
_webHost.Start();
}
void IServer.Start<TContext>(IHttpApplication<TContext> application)
{
_appFunc = async owinContext =>
{
var features = new FeatureCollection(new OwinFeatureCollection(owinContext.Environment));
var context = application.CreateContext(features);
try
{
await application.ProcessRequestAsync(context);
application.DisposeContext(context, null);
}
catch (Exception ex)
{
application.DisposeContext(context, ex);
throw;
}
};
}
public override Task Invoke(IOwinContext context)
{
if (_appFunc == null)
throw new InvalidOperationException("ASP.NET Core Web Host not started.");
return _appFunc(context);
}
public void Dispose()
{
_webHost.Dispose();
}
}

Yes, you could use WebListener web server instead of Kestrel. WebListener only works on the Windows platform but since that is where you are running, it's an option for you.
WebListener however does not rely on IIS as a reverse proxy, in fact WebListener can't be used with IIS or IIS Express since it's not compatible with ASP.NET Core Module. But it does give you a non Kestrel option for hosting ASP.NET Core on windows.
You can learn more about it here: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/weblistener
Prior to ASP.Net Core 2.2
If you must host in IIS and you don't want to use Kestrel and you are running on windows, then there are no options. On Windows, you either host with WebListener without IIS or you host with Kestrel using IIS as a reverse proxy. Those are your only two options currently on Windows.
Update: ASP.Net Core 2.2 or later Starting in ASP.Net Core 2.2 there is now support for running ASP.Net Core In Process in IIS. Under such a configuration Kestrel is not used. To learn more see In Process Hosting Model on the Microsoft Docs site or this blog post https://weblog.west-wind.com/posts/2019/Mar/16/ASPNET-Core-Hosting-on-IIS-with-ASPNET-Core-22

Related

mapbox files pbf blocked IIS server

PBF (street map mapbox vector files) files are not allowed to be served /downloaded from IIS (2008 R8) and I need them to be.
The background
PBFs are served OK when using the react development server
//Startup.cs
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
}
These files will appear on the map correctly.
However when deploying the .NET Core app to IIS with
ASPNETCORE_ENVIRONMENT = production
set. These files are essentially blocked.
I have added the MIME type
I believe this is an IIS thing as like I say, on the react server in development they load fine.
Any clues as of why they still won't download?
Thanks
Basically IIS virtual directories aren’t supported in .net core. Due to the way .net core projects are served in IIS using a reverse proxy. So in the startup.cs file, do something like this:
// Configure the virtual directory
app.UseStaticFiles(new StaticFileOptions {
FileProvider = new PhysicalFileProvider(#"\\Server\Directory\.."),
RequestPath = "/NameOfDirectory",
ContentTypeProvider = provider,
OnPrepareResponse = (context) => {
if (!context.Context.User.Identity.IsAuthenticated) {
context.Context.Response.Redirect("LoginPage");
}
}
});

Get HttpStatusCode 504 ( DNS Name Not Found ) in .Net Core 2.1 and Upper Version

I was create simple project with .netCore 2.0 and send HttpRequest with HttpClient, that is working well.
But, when I'm migrating from .netCore 2.0 to upper version ( e.g: .NetCore 2.1 or .netCore 3.0 ) this Code is not working.
My Code is:
public async Task<bool> IsValid()
{
string url = "http://api.domain.com/...";
var values = new Dictionary<string, string>()
{
{ "param1", "value1" },
{ "param2", "value2" }
};
HttpClient client = new HttpClient();
var content = new FormUrlEncodedContent(values);
var post = await client.PostAsync(url, content);
if (post.StatusCode == System.Net.HttpStatusCode.OK)
{
return true;
}
return false;
}
I expect the output of httpResponse to bo HttpStatusCode.OK. but the actual output is HttpStatusCode.GatewayTimeout.
I found that:
If I run API server ( http://api.domain.com/ ) in IIS of windows server 2012, all requests is working well.
But When I Use IIS of Windows 8, only HttpRequest with ASP.NET Core sdk 2.0 is working and others not working.
Can anyone help me?
This problem has finally been resolved.
This problem was related to the network and proxy settings in my network.
I realize when api server be in internet network, that is working well. but when api server to be used in local network, Because of using the proxy in my network, all
requests was encountered with error 504 (unless the request was sending with .netCore sdk 2.0 ).
It should be noted I had added this line 192.168.11.125 api.domain.com to host file in Directory c:\windows\system32\drivers\etc\hosts.
and also, I had added Follow Exceptions:
192.168.11.125 api.domain.com
from path:
Control Panel > Network and Internet > Internet Option > Connections Tab > Lan Settings > Advanced > Exceptions panel
But that's not working.
When I picked up the check of Use a proxy server for your lan ... in Local Area Network (LAN) Settings form, all requests working well.
Of course, this question remains that, why The same request is working with .netcore sdk 2.0 ?
what is difference between sending request with .netCore sdk 2.0 and (.netCore sdk 2.1 or .netCore sdk 2.2 or .netCore sdk 3.0)???!!!
Good luck.

SSL based webserver on Windows IoT

I am working on a project which involves gathering some sensor data and build a GUI on it, with controlling of sensors. It has following two basic requirements.
Should be a web based solution (Although it will only be used on LAN or even same PC)
It should be executable on both windows IoT core and standard windows PC (Windows 7 and above)
I have decided to use Embedded webserver for Windows IoT, which seems to be a good embedded server based on PCL targeting .NET 4.5 and UWP. So I can execute it on both environments. That is great! But the problem is this web server doesn't support SSL, I have tried to search other servers and have come up with Restup for UWP, which is also a good REST based web server, but it also doesn't support SSL.
I needs an expert opinion, that if there is any possibility I can use SSL protocol in these web servers. Is it possible that it can be implemented using some libraries like OpenSSL etc? (Although I think that it would be too complex and much time taking to implement it correctly)
Edit
I would even like to know about ASP.NET core on Windows 10 IoT Core, if I can build an application for both windows. I found one example but it is DNXbased, and I don't want to follow this way, as DNX is deprecated.
Any help is highly appreciated.
Late answer, but .NET Core 2.0 looks promising with Kestrel. I successfully created a .Net Core 2.0 app on the PI 3 this morning. Pretty nifty and If you already have an Apache web server, you’re almost done. I’m actually going to embed (might not be the right term) my .Net Core 2.0 web application into a UWP app, rather than create multiple unique apps for the touchscreens around the house.
.Net Core 2.0 is still in preview though.
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?tabs=aspnetcore2x
I know this post is pretty old, but I have built the solution which you are asking bout. I’m currently running .Net 5.0 on a Raspberry pi. When you build the .net core web project, select the correct target framework and the target runtime to win-arm. Copy the output some directory on the pi and you will have to access the device using powershell to create a scheduled task to start the web project. Something like this:
schtasks /create /tn "Startup Web" /tr c:\startup.bat /sc onstart /ru SYSTEM
That starts a bat file which runs a powershell command which has the following command:
Set-Location C:\apps\vradWebServer\ .\VradTrackerWeb.exe (the .\VradTrackerWeb.exe is on a second line in the file) - the name of the webapp.
That starts the server. If you have any web or apps posting to the webserver you will need an ssl cert. I used no-ip and let’s encrypt for this. For let’s encrypt to work, you will need an external facing web server and have the domain name point to it. Run let’s encrypt on the external server and then copy out the cert and place it in your web directory on the pi. I then have a uwp program that runs on the pi and when it starts, it gets it’s local address and then updates no-ip with the local address, so the local devices communicating will be correctly routed and have the ssl cert. Side note, my uwp app is the startup app on the device. The scheduled task is important because it allows you to run you app and the web server. The following snip is how I get the ip address and then update no-ip.
private string GetLocalIP()
{
string localIP = "";
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect("8.8.8.8", 65530);
IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
localIP = endPoint.Address.ToString();
}
return localIP;
}//GetLocalIP
private async void UpdateIP()
{
string localIP = "";
string msg = "";
var client = new HttpClient(new HttpClientHandler { Credentials = new NetworkCredential("YourUserName", "YourPassword") });
try
{
localIP = GetLocalIP();
string noipuri = "http://dynupdate.no-ip.com/nic/update?hostname=YourDoman.hopto.org&myip=" + localIP;
using (var response = await client.GetAsync(noipuri))
using (var content = response.Content)
{
msg= await content.ReadAsStringAsync();
}
if (msg.Contains("good") == true || msg.Contains("nochg")==true)
{
SentDynamicIP = true;
LastIPAddress = localIP;
}
else
{
SentDynamicIP = false;
}
}
catch(Exception ex)
{
string x = ex.Message;
}
finally
{
client.Dispose();
}
}//UpdateIP

ASP.NET Core Identity Implementation using Cassandra Database

I am building an ASP.NET Core MVC application using the Cassandra Database on Windows.
I need help implementing ASP.NET Core Identity with Cassandra.
On Google I found AspNet.Identity.Cassandra in the version 2.0.0.1, but it's not compatible with ASP.NET Core 1.0.
I'm working on data store adapter for ASP.NET Core Identity
which allows you to build ASP.NET Core web applications, including membership, login, and user data. With this library, you can store your user's membership related data on Apache Cassandra.
Please note the library is in alpha version and needs to be finished
If you want to try it, follow these steps:
1 - Run the following command from the package manager console to install Cassandra identity provider.
Install-Package AspNetCore.Identity.Cassandra -Version 1.0.0-alpha1
2 - Add settings to appsettings.json
{
"CassandraNodes": [
"127.0.0.1"
],
"CassandraOptions": {
"KeyspaceName": "identity",
"Replication": {
"class": "NetworkTopologyStrategy",
"datacenter1": "1"
}
}
}
3 - Configure services in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
// CassandraOptions configuration
services.Configure<CassandraOptions>(Configuration.GetSection("CassandraOptions"));
// Cassandra ISession initialization
services.AddCassandraSession<Cassandra.ISession>(() =>
{
var cluster = Cassandra.Cluster.Builder()
.AddContactPoints(Configuration.GetSection("CassandraNodes").GetChildren().Select(x => x.Value))
.Build();
var session = cluster.Connect();
return session;
});
// Added custom Cassandra stores
services.AddIdentity<ApplicationUser, ApplicationRole>()
.UseCassandraStores<Cassandra.ISession>()
.AddDefaultTokenProviders();
// Other code omitted
}
4 - And finally initialize DB in Program.cs
public static class Program
{
public static void Main(string[] args)
{
BuildWebHost(args).Run();
}
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.InitializeIdentityDb<ApplicationUser, ApplicationRole>();
}
For more information check project site at github.
Few Option
Try implement your own cassandra identity for ASP.net core, there is many sample how to create your Custom IdentityUser for ASP.net (using Google) then make it work with Cassandra
Fork / Update the AspNet.Identity.Cassandra project to .net core (open source, so makes easy to implement your own)
Use another provider, instead of Cassandra Database
Request update on github (link on section 2.)

SignalR works partially on Remote Server IIS 7.5. Works fine in VS 2012. MVC4

There are similar questions but mine is a peculiar case. My signalr application works only partially on IIS 7.5
My SignalR implementation is working only partially.
I'm using SignalR 1.3, .Net Framework 4.0. MVC4
and IIS 7.5 on Wondows 2008r2
The following lines of code do execute. I get an alert and I'm able to send a message to all the clients.
$.connection.hub.start().done(function () {
alert("hi signalr started")
$('#sendmessage').click(function () {
chat.server.send($('#displayname').val(), $('#message').val());
$('#message').val('').focus();
});
});
But
public override Task OnConnected()
{
Clients.Caller.getClientName();
return base.OnConnected();
}
This method is failing to call client method getClientName().
chat.client.getClientName = function () {
//a method that the onConnect method calls to get the user's name
alert("hi");
};
I don't get an alert in this case.
Everything is working fine if I run it on VS 2012.
Please help
Did you add support for extensionless URLs?
http://support.microsoft.com/kb/980368
Also note you will need to update your web server to IIS 8.0 to get WebSockets support.
For further details, see the Supported Platforms doc"
http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/supported-platforms

Resources