HttpClient as singleton in dotnet core - asp.net-core

On the full framework there was a pattern that came out making HttpClient a singleton. This is because the existing connections could be reused, however on the full framework there were dns caching issues when doing this. Mostly when you would run httpclient as a singleton on the full framework it would cache the dns results, and you would have to use ServicePointManager to force it to refresh once in a while.
Now dotnet core LTS currently does not have ServicePointManager, so my question is. Can you run HttpClient as a singleton in dotnet core and have it respect DNS updates?

I am quoting a post from the link below
"Unfortunately, there's no way to do this with .NET Core today.
Either ServicePointManager should be brought over to .NET Core or similar equivalent functionality should be enabled some other way."
Here is the link that might be worth checking: https://github.com/dotnet/corefx/issues/11224

I'm also using HTTPClient as a singleton and injecting it into the controllers in my .NET Core APIs.
I can confirm that ServicePointManager exists in .NET Core Runtime 2.0.5.
I'm using the following, after I've created the request to solve DNS issues.
Uri vRequestUri = new Uri ("https:api.example.com/....");
HttpRequestMessage vRequest = new HttpRequestMessage (HttpMethod.Post, vRequestUri);
ServicePoint vSP = ServicePointManager.FindServicePoint (vRequest.RequestUri);
vSP.ConnectionLeaseTimeout = 60 * 1000; // 1 Minute
For those who are not aware of the DNS problem, the following article would be informative http://byterot.blogspot.com.tr/2016/07/singleton-httpclient-dns.html

I have done it using the new SocketsHttpHandler
var handler = new SocketsHttpHandler()
{
ConnectTimeout = TimeSpan.FromMinutes(1),
PooledConnectionLifetime = TimeSpan.FromMinutes(5) //https://github.com/dotnet/corefx/issues/26331
};
var client = new HttpClient(handler){};

This should be fixed in dotnet core 2.1, currently available in preview.

Related

How to republish an ASP.NET Core 5 web application in IIS. Changes not taking effect

I've published an ASP.NET Core 5 Web API to IIS (using VS 2019 webdeploy), and it is running fine. Now I've made some minor changes and republished.
The changes take affect on my local machine using IIS Express, but I do not see them when I publish to my IIS server. I can see that the exe and dlls are updated, but the webapi behaviour does change.
Something as simple as setting the swaggerdoc title doesn't take affect.
Is there something else I need to do to refresh the app? I've tried recycling the app pool and doing an iisreset, but no luck. I've read that IIS is merely acting as a reverse proxy to Kestrel which is actually hosting the api. If so how do I recycle that?
As a test, I delete all the files in my web api directory. I browse to the web api and get the following error:
HTTP Error 500.31 - Failed to load ASP.NET Core runtime Common
solutions to this issue: The specified version of
Microsoft.NetCore.App or Microsoft.AspNetCore.App was not found.
Troubleshooting steps:
Check the system event log for error messages
Enable logging the application process' stdout messages Attach a
debugger to the application process and inspect For more information
visit: https://go.microsoft.com/fwlink/?LinkID=2028526
I then re-publish the web api and browse to it, but it still has the old behavior. I'm really confused, because I know the published dll for my service is correct.
If I use ILSpy I can see the following code:
public void ConfigureServices(IServiceCollection services)
{
IConfigurationSection appSettingsSection = Configuration.GetSection("ApplicationSettings");
ApplicationSettings appSettings = appSettingsSection.Get<ApplicationSettings>();
services.AddSingleton(appSettingsSection.Get<ApplicationSettings>());
services.AddControllers()
.AddXmlSerializerFormatters()
.AddJsonOptions(delegate(JsonOptions o)
{
o.JsonSerializerOptions.PropertyNamingPolicy = null;
o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
});
services.AddSwaggerGen(delegate(SwaggerGenOptions c)
{
c.SwaggerDoc("v1", new OpenApiInfo
{
Title = "My Demo Service (" + appSettings.Environment + ")",
Version = "v1"
});
});
}
When I browse to the swagger page of my API on my local dev box the title matches code, and the property naming is what I want. When I browse to it on the server, the title of the swagger page is the old value, and the property naming policy is camel case, so I'm pretty sure I'm publishing the new version of my web api, but it's not being executed when I make http requests to the api. Something must be cached somewhere.

WebSockets Server .NET Core - IsWebSocketRequest always returns false

I'm using what I consider some fairly "standard" code in .NET Core to implement a web socket server:
if (ctx.Request.Path == "/api/v1/sometest")
{
if (ctx.WebSockets.IsWebSocketRequest)
{
WebSocket wsSock = await ctx.WebSockets.AcceptWebSocketAsync();
But I can never establish a session because IsWebSocketRequest is always null.
I can see the Connection: Upgrade and Upgrade: websocket headers...
I know I must be missing something but unsure what... Scanned through github dotnet source code to see if I could figure it out that way but no luck finding a solution yet.
I'm using Windows 10
Kestrel
VS Code
.NET Core 3.1
I had AddWebSockets in Startup.ConfigureServices BUT I forgot to also include the middleware in Startup.Configure. Call app.UseWebSockets here to register the middleware in your chain.
According to this link app.UseWebSockets() should be placed right before app.UseEndpoints() in startup.cs .

Can no longer access the list of API descriptors after installing Glimpse

We would like to use Glimpse in our ASP.net MVC project but are running into a problem when accessing the list of Web API descriptors.
We have installed Glimpse.Mvc4 1.2.2 using the Nuget Package Manager.
The following snippet gets all API descriptors and it works fine before we install Glimpse. After installing we do only get an empty list.
IEnumerable<ApiDescription> apiDescriptors = System.Web.Http.GlobalConfiguration
.Configuration
.Services
.GetApiExplorer()
.ApiDescriptions
Does anyone know why this call does not work when Glimpse is installed?
The problem is that the Glimpse ASP.NET module wraps all routes in its own objects. So API Explorer ignores them (thinks that they are not Web API routes).
To work around this issue, you must initialize a fresh copy of System.Web.Http.HttpConfiguration instead of using GlobalConfiguration.Configuration.
// need to create a custom configuration instance because the default one can be
// processed by Glimpse and be thus full of wrapped routesthat the ApiExplorer
// does not recognize.
var config = new System.Web.Http.HttpConfiguration();
WebApiConfig.Register(config);
// these line is useful if you use WebAPI Help page package
HelpPageConfig.Register(config);
Controllers.HelpController.Configuration = config;
// otherwise just get the `IApiExplorer` interface from the fresh configuration:
var apis = config.Services.GetApiExplorer().ApiDescriptions;

Autobinding in MVC4 WebApi with Ninject.Extensions.Conventions

In my MVC4 app I'm using Ninject.Extensions.Conventions to autobind all itnerfaces with their implementation using default mechanism:
kernel.Bind(x => x
.FromAssembliesMatching("*")
.SelectAllClasses()
.BindDefaultInterface());
This works great for regular controllers, but doesn't for WebApi controllers. What do I need to change/add?
Ok, I resolved the issue by following this article:
http://www.peterprovost.org/blog/2012/06/19/adding-ninject-to-web-api/
In short: I created my own dependency resolver (as per article) and assigned it to GlobalConfiguration.Configuration.DependencyResolver as suggested by nemesv
There are already a many examples on how to integrate NInject with Web API through the web, using:
DependencyResolver
On ASP.NET website is shown standart way of integration of any DI/IoC with Web API:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
IDependencyResolver.
WebApiContrib project shows how to do it with IDependencyResolver
https://github.com/WebApiContrib/WebApiContrib.IoC.Ninject
Please post more information about your implementation of these resolvers, to be more specific in answer.

ASP.NET WebAPI fails from MVC4 controller

I'm new to ASP.NET Web API and I'm struggling with a very strange problem.
I have some code which calls a RESTful service and it executes fine from a console project, but I can't get it to run from an MVC4 project running under .NET 4.0
The code to call the service is very simple:
internal string Test()
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://testserver");
var task = client.GetAsync("/someUri")
var response = task.Result;
response.EnsureSuccessStatusCode();
return response.Content.ReadAsStringAsync().Result;
}
}
As mentioned, called from a console project it works as expected and I get a response in milliseconds, however if I call the method from an action in my MVC4 controller after a few seconds I get a message stating that:
"A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to repond".
Weirdly, when debugging the MVC4 version, the task status always shows as WaitingForActivation.
Running fiddler doesn't show any request being made from the MVC4 version, but again does for the Console version.
After a fairly serious bit of googling I can't find anyone else who seems to have had this problem, so I'm guessing that I've fundamentally misunderstood something, but at the moment I'm not sure what!
Updated 16:55 BST, 11/09/2012
To make things even weirder, I've just created a new MVC4 site and I can call the method without any problems! I'm now trying to compare the sites, however one was an existing site that was upgraded to MVC4 and the other is a new blank site, so spotting the relevant difference could be tricky.
Updated 16:44 BST, 14/09/2012
This is now looking like some infrastructure / networking issue.
I upgraded the project to VS2012 with .NET 4.5 so that I could use async/await to try the suggested implementations to avoid a deadlock. This didn't change anything so I went back to square 1.
I created a new solution with a new MVC4 project, a new services library and a unit test project to run the service library outside of MVC.
In the service library I created one method to call a public "what's my IP" service, and another to call a company service that's exposed publicly but only responds properly to company IP addresses.
For some background, I connect in to the company LAN via a VPN.
When disconnected from the VPN, in both unit tests and MVC, the IP service responds HTTP 200, the company service responds HTTP 404 as expected.
When connected to the VPN, unit tests both respond HTTP 200, MVC both timeout.
Next I ran MS Soap Tool locally and used that to proxy calls to the company services. All calls (whether from unit tests or MVC) show a request and response, but the unit test registers the response whilst the MVC controller does not.
My only other thought is that it could be something to do with the size of the reply? All the "successes" have very small replies other than the unit test calling the company service?
The Microsoft recommended way to upgrade an MVC3 to MVC4 site is to start with a completely new MVC4 site a migrate your views, controllers & code over. So I think that your upgrade steps may be part of your issue, since you were able to get it to work in the new MVC4 site you created. If you need to manually upgrade your existing site, I would follow the steps outlined in Upgrading ASP.NET MVC 3 Project to ASP.NET MVC 4