ribs
ribs

Reputation: 75

How to migrate ASP.NET Framework configurations to ASP.NET Core?

I'm migrating an ASP.NET Framework application hosted on IIS to ASP.NET Core hosted on Kestrel.

In ASP.NET Framework, I have a web.config with dozens of custom configurations/optimizations, like:

<httpRuntime executionTimeout="120" maxUrlLength="8192" maxQueryStringLength="8192" />

Problem is that I can't find how to configuration those settings, like maxQueryStringLength in ASP.NET Core with Kestrel.

For example, in this answer, the user says that it is not available in ASP.NET Core and recommends to use IIS or NGINX.

How can I migrate my web.config settings without using a web.config file in ASP.NET Core? I would prefer to use the default appsettings.json file.

Upvotes: 2

Views: 3287

Answers (1)

Andrii
Andrii

Reputation: 81

You may use ASP.NET Core Kestrel limits to make the appropriate configs

https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.server.kestrel.core.kestrelserverlimits?view=aspnetcore-3.1

It could be done via configs in Program.cs

#elif Limits
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    #region snippet_Limits
                    webBuilder.ConfigureKestrel(serverOptions =>
                    {
                        serverOptions.Limits.MaxConcurrentConnections = 100;
                        serverOptions.Limits.MaxConcurrentUpgradedConnections = 100;
                        serverOptions.Limits.MaxRequestBodySize = 10 * 1024;
                        serverOptions.Limits.MinRequestBodyDataRate =
                            new MinDataRate(bytesPerSecond: 100, 
                                gracePeriod: TimeSpan.FromSeconds(10));
                        serverOptions.Limits.MinResponseDataRate =
                            new MinDataRate(bytesPerSecond: 100, 
                                gracePeriod: TimeSpan.FromSeconds(10));
                        serverOptions.Listen(IPAddress.Loopback, 5000);
                        serverOptions.Listen(IPAddress.Loopback, 5001, 
                            listenOptions =>
                            {
                                listenOptions.UseHttps("testCert.pfx", 
                                    "testPassword");
                            });
                        serverOptions.Limits.KeepAliveTimeout = 
                            TimeSpan.FromMinutes(2);
                        serverOptions.Limits.RequestHeadersTimeout = 
                            TimeSpan.FromMinutes(1);
                    })
                    #endregion
                    .UseStartup<Startup>();
                });
#elif Port0

Kestrel options can also be set using a configuration provider. For example, the File Configuration Provider ( https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/?view=aspnetcore-3.1#file-configuration-provider ) can load Kestrel configuration from an appsettings.json or appsettings.{Environment}.json file:

{
  "Kestrel": {
    "Limits": {
      "MaxConcurrentConnections": 100,
      "MaxConcurrentUpgradedConnections": 100
    },
    "DisableStringReuse": true
  }
}

Also, if you need to manage these things via code you may try to handle it via middleware

public class RequestFilterMiddleware
    {
        private readonly RequestDelegate _next;
        private const long _allowedRequestQueryStringMaxLength = 100;
        private const long _allowedUrlStringMaxLength = 100;
        public RequestFilterMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
            var queryStringLength = httpContext.Request.QueryString.Value?.Length;
            if (queryStringLength > _allowedRequestQueryStringMaxLength)
            {
                //throw exception or send some appropriate http status code
            }

            var urlRequestLength = httpContext.Request.GetDisplayUrl().Length;
            if (urlRequestLength > _allowedUrlStringMaxLength)
            {
                //throw exception or send some appropriate http status code
            }

            using (var TokenSource = System.Threading.CancellationTokenSource.CreateLinkedTokenSource(httpContext.RequestAborted))
            {
                httpContext.RequestAborted = TokenSource.Token;
                var DelayTask = Task.Delay(500, TokenSource.Token);
                var NextTask = _next.Invoke(httpContext);
                if (await Task.WhenAny(DelayTask, NextTask).ConfigureAwait(false) == DelayTask)
                {
                    //LogStuff for long running requests
                   
                }
                TokenSource.Cancel();
            }

            await _next(httpContext);
        }
    }

Unfortunately, the timeout option is not available in Kestrel at this moment, to get more information you may read this topic https://github.com/dotnet/aspnetcore/issues/10079

However, it's possible at least to log long running requests in production for later optimization purposes.

Upvotes: 4

Related Questions