.NET Code Tips

Free .NET developer tool

web.config to appsettings.json Converter

Migrating ASP.NET MVC 5 or Web API to ASP.NET Core? Paste your web.config to get the appsettings.json, plus a checklist of what moves into Program.cs.

Runs entirely in your browser — nothing you paste is uploaded.

appsettings.json · 5 settings, 1 connection strings
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.;Database=Northwind;Integrated Security=True;MultipleActiveResultSets=True"
  },
  "ApplicationInsights": {
    "ConnectionString": "InstrumentationKey=00000000-0000-0000-0000-000000000000"
  },
  "AppSettings": {
    "Smtp": {
      "Host": "smtp.contoso.com",
      "Port": 587
    },
    "FeatureFlags": {
      "NewCheckout": true
    },
    "ApiBaseUrl": "https://api.contoso.com/v2/"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*"
}

Migration checklist (9)

Settings that don't belong in appsettings.json, and what replaces them in ASP.NET Core.

  • Info
    connectionStrings/@providerName

    providerName has no place in appsettings.json — the provider is chosen in code (UseSqlServer, UseNpgsql…). Found: DefaultConnection: System.Data.SqlClient.

  • Info
    appSettings/webpages:Version

    An ASP.NET MVC 5 framework switch with no meaning in ASP.NET Core, so it was left out.

  • Action
    appSettings/APPINSIGHTS_INSTRUMENTATIONKEY

    Instrumentation keys are deprecated, so the key was moved to "ApplicationInsights:ConnectionString" (copy the full connection string from the Azure portal for the right ingestion endpoint). Call builder.Services.AddApplicationInsightsTelemetry(). To turn telemetry off for Debug builds, leave the connection string out of appsettings.Development.json.

  • Info
    system.web/compilation

    debug="true" and targetFramework have no equivalent: build configuration (Debug/Release) and the project's <TargetFramework> replace them. Use ASPNETCORE_ENVIRONMENT=Development for developer behavior.

  • Action
    system.web/httpRuntime

    maxRequestLength (10240 KB) becomes Kestrel's Limits.MaxRequestBodySize or FormOptions.MultipartBodyLengthLimit; under IIS also keep requestFiltering's maxAllowedContentLength in web.config. executionTimeout has no direct equivalent.

  • Action
    system.web/customErrors

    Use app.UseExceptionHandler("/Error") for 500s and app.UseStatusCodePagesWithReExecute("/Error/{0}") for 404s in Program.cs; use app.UseDeveloperExceptionPage() only in Development.

  • Action
    system.web/authentication

    Forms authentication becomes cookie authentication: builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(o => o.LoginPath = "/Account/Login"), plus app.UseAuthentication().

  • Action
    system.webServer/rewrite

    1 rewrite rule: keep them in web.config when hosting on IIS, or move them into the app with Microsoft.AspNetCore.Rewrite — new RewriteOptions().AddIISUrlRewrite(env.ContentRootFileProvider, "IISUrlRewrite.xml") reads this exact XML format. For www/https redirects prefer app.UseHttpsRedirection() and AddRedirectToNonWww().

  • Action
    system.webServer/httpErrors

    Custom error pages become app.UseStatusCodePagesWithReExecute("/Error/{0}") in Program.cs.

From ConfigurationManager to IConfiguration

In ASP.NET Core, ConfigurationManager.AppSettings["Key"] becomes IConfiguration, which layers appsettings.json, appsettings.{Environment}.json, user secrets, environment variables and command-line arguments — later sources override earlier ones. Colons in keys become nested JSON sections, and a section binds to a plain class with the options pattern:

Options pattern
// appsettings.json: { "Smtp": { "Host": "smtp.contoso.com", "Port": 587 } }
public sealed class SmtpOptions
{
    public string Host { get; set; } = "";
    public int Port { get; set; } = 25;
}

// Program.cs
builder.Services.Configure<SmtpOptions>(builder.Configuration.GetSection("Smtp"));
string? cs = builder.Configuration.GetConnectionString("DefaultConnection");
string? api = builder.Configuration["AppSettings:ApiBaseUrl"];

// Anywhere: inject IOptions<SmtpOptions> instead of reading ConfigurationManager.AppSettings
public class Mailer(IOptions<SmtpOptions> smtp) { /* smtp.Value.Host */ }

RedirectToAction with route parameters

Controllers carry over almost unchanged. RedirectToAction still takes an anonymous object of route values — members that match the route template fill it in, the rest become the query string — and ASP.NET Core adds permanent (301) and method-preserving (307/308) variants:

OrdersController.cs
public class OrdersController : Controller
{
    [HttpPost]
    public IActionResult Create(OrderForm form)
    {
        var id = _orders.Add(form);

        // 302 to /Orders/Details/42?tab=lines — anonymous-object members become
        // route values; any not used by the route template become the query string.
        return RedirectToAction(nameof(Details), new { id, tab = "lines" });

        // Other controller:   RedirectToAction("Index", "Home", new { area = "" })
        // 301 permanent:      RedirectToActionPermanent(nameof(Details), new { id })
        // 307 (keeps POST):   RedirectToActionPreserveMethod(nameof(Details), routeValues: new { id })
    }
}

// Minimal APIs
app.MapPost("/orders", (Order o) => Results.RedirectToRoute("order-details", new { id = o.Id }));

URL Rewrite rules, www and HTTPS redirects

When you host on IIS you can keep <rewrite> rules in the web.config that dotnet publish generates. To make them part of the app — so they also apply under Kestrel, in containers or on Linux — use the rewrite middleware, which can even read the IIS rule XML directly:

Program.cs
using Microsoft.AspNetCore.Rewrite;

var rewrite = new RewriteOptions()
    .AddRedirectToNonWwwPermanent()                 // www.example.com → example.com (301)
    .AddRedirectToHttpsPermanent()                  // http → https (301)
    .AddRedirect("^Tip/(\\d+)/.*", "tips/$1", 301)    // regex redirect
    .AddIISUrlRewrite(builder.Environment.ContentRootFileProvider, "IISUrlRewrite.xml");

app.UseRewriter(rewrite);

Custom error pages

<customErrors> and <httpErrors> become two lines of middleware. Re-executing keeps the original status code, so a missing page still answers 404 and isn't indexed as a duplicate:

Program.cs
// Replaces <customErrors> and <httpErrors>
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Error");               // unhandled exceptions → 500 page
    app.UseHsts();
}
app.UseStatusCodePagesWithReExecute("/Error/{0}");  // 404 etc., keeps the status code

Frequently asked questions

Where do web.config appSettings go in ASP.NET Core?

Into appsettings.json, read through IConfiguration. A flat key such as "ApiBaseUrl" becomes builder.Configuration["ApiBaseUrl"], and keys using colons such as "Smtp:Host" become nested JSON sections that can be bound to a strongly typed options class with builder.Services.Configure<SmtpOptions>(builder.Configuration.GetSection("Smtp")).

How do I read a connection string in ASP.NET Core?

Put it under the "ConnectionStrings" section of appsettings.json and call builder.Configuration.GetConnectionString("DefaultConnection"). The providerName attribute from web.config has no equivalent; the provider is chosen in code, for example options.UseSqlServer(...) for Entity Framework Core. Keep passwords out of appsettings.json with user secrets in development and environment variables or Azure Key Vault in production.

Does ASP.NET Core still use web.config?

Only when hosted in IIS, and only for IIS itself. dotnet publish generates a small web.config that registers the ASP.NET Core Module, and IIS-level settings such as URL Rewrite rules, requestFiltering limits and static compression can still live there. Application settings, authentication, session and error handling are configured in Program.cs and appsettings.json instead.

What replaces RedirectToAction with route parameters in ASP.NET Core?

RedirectToAction works the same way in ASP.NET Core MVC: return RedirectToAction("Details", "Orders", new { id = 42 }) produces a 302 to the Details action with id as a route value or query string parameter. ASP.NET Core adds RedirectToActionPermanent for a 301 and RedirectToActionPreserveMethod for a 307 that keeps the POST, and in Minimal APIs you return Results.RedirectToRoute or Results.Redirect.