Convert Web API to use Self Hosting - c#

I am trying to convert an existing ASP.NET Web API project (currently hosted in IIS) into one that can use the SelfHost framework. I'm a bit fuzzy on the actual details but understand I can run a self-host server in a console window and then run the service on top of it. The problem I'm having is that my project is an MVC project and not a console one. My familiarity with console/Windows apps is somewhat limited as I generally work with projects to be hosted in IIS.
What I'm a bit confused on is whether I need to convert my existing Web API project in Visual Studio into a new console application, or if there's a way to create another console application Project in the solution which can act as the web server for the Web API services, or rather if there's a way to add a console element with a Main() entry point to the existing MVC project (overriding the Global.asax entry point.)
Search didn't yield much information that helps me fill this knowledge gap. Hoping someone can point me in the right direction. Even at a high level.

I recently had to convert a Web API project into a self-hosted service using OWIN (on Visual Studio 2013). I did that as follows:
Manually added Program.cs and Startup.cs files at the root of the project. Both files containing code as described here: http://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api.
Went to the properties of the Web API project. On the "Applications" section, I stated "Output Type" as "Console Application", and set the "Program" class as the "Startup object".
Although not required, I slightly modified the using block within Program.Main() to look as follows:
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpCient and make a request to api/values
HttpClient client = new HttpClient();
var response = client.GetAsync(baseAddress + "api/values").Result;
if (response != null)
{
Console.WriteLine("Information from service: {0}", response.Content.ReadAsStringAsync().Result);
}
else
{
Console.WriteLine("ERROR: Impossible to connect to service");
}
Console.WriteLine();
Console.WriteLine("Press ENTER to stop the server and close app...");
Console.ReadLine();
}
Finally, instead of calling config.Routes.MapHttpRoute() multiple times within Startup.Configuration(), you can refer to the routes you already wrote for the Web API:
// Configure Web API for self-host.
var config = new HttpConfiguration();
WebApiConfig.Register(config);
app.UseWebApi(config);

Related

IdentityServer 3 hanging on the GetConfiguration() call

I have just started working on IS 3 project which is already there. The architecture we currently have is
1) WCF REST and WCF Soap in one WCF service project
2) Owin middle layer which is a class library which is a separate project
3) Identity Server 3 which is a web project within the same solution as the previous 2
I have just added a brand new Web API project (Ver 1) into the same solution and I am trying to utilize the same code, so that I can share the calls with the WCF project.
I have implemented separate classes called HttpHeaderInformationForWebAPI and all that and I am sending my ApiControler.Request object all the way to this Owin layer.
If I try a request for the existing WCF Rest method, the code works fine and it validates the token just fine.
But when I try to validate the token via my new Web Api, it hangs at this line.
private async Task<OpenIdConnectConfiguration> RetrieveConfiguration()
{
ConfigurationManager<OpenIdConnectConfiguration> configurationManager = new ConfigurationManager<OpenIdConnectConfiguration>(IDPBaseAddress + "/.well-known/openid-configuration");
configurationManager.AutomaticRefreshInterval = new TimeSpan(1, 0, 0, 0);
return await configurationManager.GetConfigurationAsync().ConfigureAwait(false);
}
It hangs at the return await line and just hangs there. If I look at the IdentitySerever logs, it says "Starting Discovery" and hangs there. Am I missing any config entries?
As far as I know the Middleware is handling everything and I don't need any web.config values at my end other than the Base Address and other end point URLs related to IS.
Can you please let me know what I am missing? Most of the samples are within the same project on GitHub. Here it is a 3-tier setup and I am really struggling if I need anything in Global.asax on my API project. If I look at the existing WCF service project, there is nothing configured related to OWIN or IS or no startup.cs and it works fine. But the same line hangs when called from my web api, even though I can get that config file to load on my browser.
Thanks!

Is there way to create a true selfhosted .Net ( Core) wepApp without any proxy

I can in ASP.NET and .NET Core create a selfhosted web service (WCF,REST, based on Kastrel or Katana and so on). But is there a way to create a full working web site, or SPA, may be based MVC ?
For example I can inside .NET Core Startup file add code:
app.Run(async (context) =>
{
await context.Response.WriteAsync($"Hello World! {
//insert your web site here :-)
}");
});
- but I should to create all html, js and so on code by myself. May be we have a better way ?
Of course I know that we have a big parts like ASP and so on - but we can't create selfhosted app, we need a web server - usually IIS !
I guess you mean that your self-hosted web server of visual studio is not accessible from the outside?
Assuming that your port forwarding and firewall are correctly configured. You need to change the bind address of your application:
new WebHostBuilder()
.UseKestrel()
...
.UseUrls("http://*:80")
...;
Note:
This should never be used without reverse proxy.
More info about why this should not be done without reverse proxy: https://learn.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-2.0&tabs=aspnetcore2x

How to run self-hosted(owin based) web api on IIS?

I have developed self-hosted(owin based) web api using console application.
In development phase I was running the console application and everything was okay.
static void Main(string[] args)
{
string baseUri = "http://+:8080";
Console.WriteLine("Starting web Server...");
var server = WebApp.Start<Startup>(baseUri);
Console.WriteLine("Server running at {0} - press Enter to quit. ", baseUri);
Console.ReadLine();
server.Dispose();
}
Now I need to deploy my self-hosted web api to run on IIS.So, could you please tell me the steps to get my web api up and running on IIS?
In order to understand theory - take a look at this question. If you want your OWIN self-hosted WEB API application to be running on IIS, you need to use Owin.Host.SystemWeb package. You should:
Add a Startup.cs class (entry point for your IIS-hosted app)
Tell OWIN pipeline about your entrypoint: Mark Startup class with
owin attribute OR do it via web.config. (See this article for reference)
P.S. You can always take a look at a standard scaffolded empty Web API project in Visual Studio. It includes IIS web host out-of-the-box

WCF Service Endpoints not reachable from local

I am new to WCF development and I am trying to create a WCF service hosted in a console app.
I have already created the WCF service and tested it by running it on IIS Express. Doing so, the WCF service will be accessible from http://localhost:5576/MyFirstService.svc. Within the service, I have defined a GET endpoint /test/<param> just to test if it works. Upon visiting the url with Postman http://localhost:5576/MyFirstService.svc/test/123, it will echo back 123.
My console app that hosts the WCF on the other hand is super simple. I followed the tutorial (http://www.topwcftutorials.net/2014/05/wcf-self-hosting-console-application.html). The relevant code is below:
Uri httpBaseAddress = new Uri("http://localhost:4321/StudentService");
//Instantiate ServiceHost
studentServiceHost = new ServiceHost(typeof(StudentService.StudentService), httpBaseAddress);
//Add Endpoint to Host
studentServiceHost.AddServiceEndpoint(typeof(StudentService.IStudentService), new WSHttpBinding(), "");
//Metadata Exchange
ServiceMetadataBehavior serviceBehavior = new ServiceMetadataBehavior();
serviceBehavior.HttpGetEnabled = true;
studentServiceHost.Description.Behaviors.Add(serviceBehavior);
//Open
studentServiceHost.Open();
Console.WriteLine("Service is live now at : {0}", httpBaseAddress);
Console.ReadKey();
As I launched the console app and visited http://localhost:4321/StudentService, I am greeted with the standard page talking about wsdl. However, if I tried to visit http://localhost:4321/StudentService/test/123, I get a 400 bad request error.
Am I doing things right? What is the path that I should be using to get to my endpoints? I tried many variations of the URL and it just does not seem to work.
Your first service, http://localhost:5576/MyFirstService.svc, was running within the context of IIS (yes even though it's express) so that is what allows for the URL (REST style) routing like you were seeing in your "test/123" example.
But the code example, and posted reference link, is actually a self-hosted service from a console application which doesn't utilize IIS or WAS (Windows Activation Service) so routing won't be available.
Don't get me wrong, your StudentService will still work just fine if called via SOAP, just not from a REST perspective which is what Postman is used for.
There are free tools out there like SoapUI that work just like Postman to test your WCF services.

Calling Application_Start in Owin Self-Hosting application

I have an ASP WebAPI application that works great.
Without changing anything massive within the application, I'm trying to create a new console project with self-hosting components to host the application (mainly for running it fast when debugging other components of my solution without opening and compiling from Visual Studio).
I saw plenty of solutions for using Microsoft.AspNet.SignalR.SelfHost package,
For example: Working With OWIN Hosting and Self Hosting in ASP.Net.
All the solutions I saw, use the following structure:
string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpCient and make a request to api/values
HttpClient client = new HttpClient();
var response = client.GetAsync(baseAddress + "api/values").Result;
Console.WriteLine(response);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
}
Console.ReadLine();
This is a bit problematic for me, since using (WebApp.Start<Startup>(url: baseAddress)) is calling the Configuration method in Startup class.
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{ ... }
}
My solution has plenty of code inside the Application_Start() (inside the Global.aspx.cs file) that I'm trying to reach when starting the console self-host application. So far without any success.
Is this a lost battle and I should move as much as I can from Application_Start method to Configuration method? Or is there any way I call call the Application_Start somehow, prior to running the Configuration method?
I tried creating an instance of the ASP application and call the Application_Start, but that didn't work.
Thanks!
Guy

Categories

Resources