TekOnline

ASP.NET MVC to .NET Core MVC Migration Cheat Sheet

Partial Views

ASP.NET MVC (Legacy)

// Render partial with no return value (writes directly to response)
@Html.RenderPartial("_PartialName", model)

// Render partial and return as string
@Html.Partial("_PartialName", model)

// Render action
@Html.RenderAction("ActionName", "ControllerName")
@Html.Action("ActionName", "ControllerName")

.NET Core MVC

// Use PartialAsync (recommended)
@await Html.PartialAsync("_PartialName", model)

// Use RenderPartialAsync for direct writing
@{ await Html.RenderPartialAsync("_PartialName", model); }

// Use View Components instead of RenderAction
@await Component.InvokeAsync("ComponentName", new { parameter = value })
<!-- Use the <partial> tag helper (most modern approach) -->
<partial name="_PartialName" model="model" />
<partial name="Shared/_ProductPartial" for="Product" />

<!-- With additional view data -->
<partial name="_PartialName" model="model" view-data="ViewData" />

HTML Helpers vs Tag Helpers

ASP.NET MVC (Legacy)

@Html.TextBoxFor(m => m.Name, new { @class = "form-control" })
@Html.DropDownListFor(m => m.CategoryId, ViewBag.Categories as SelectList, "Select...", new { @class = "form-control" })
@Html.ValidationMessageFor(m => m.Name)
@Html.BeginForm("Action", "Controller", FormMethod.Post, new { @class = "form" })

.NET Core MVC

<input asp-for="Name" class="form-control" />
<select asp-for="CategoryId" asp-items="ViewBag.Categories" class="form-control">
    <option value="">Select...</option>
</select>
<span asp-validation-for="Name"></span>
<form asp-action="Action" asp-controller="Controller" method="post" class="form">

Configuration

ASP.NET MVC (Legacy – Web.config)

<configuration>
  <connectionStrings>
    <add name="DefaultConnection" connectionString="..." />
  </connectionStrings>
  <appSettings>
    <add key="Setting1" value="Value1" />
  </appSettings>
</configuration>

.NET Core MVC (appsettings.json)

{
  "ConnectionStrings": {
    "DefaultConnection": "..."
  },
  "AppSettings": {
    "Setting1": "Value1"
  }
}

Dependency Injection

ASP.NET MVC (Legacy)

// In Global.asax.cs or using external DI container
public class MvcApplication : HttpApplication
{
    protected void Application_Start()
    {
        // Manual dependency setup
    }
}

.NET Core MVC

// In Startup.cs or Program.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddScoped<IService, ServiceImplementation>();
    services.AddDbContext<ApplicationDbContext>(options =>
        options.UseSqlServer(connectionString));
}

Action Filters

ASP.NET MVC (Legacy)

public class CustomActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        // Pre-action logic
    }
    
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        // Post-action logic
    }
}

.NET Core MVC

public class CustomActionFilter : IActionFilter
{
    public void OnActionExecuting(ActionExecutingContext context)
    {
        // Pre-action logic
    }
    
    public void OnActionExecuted(ActionExecutedContext context)
    {
        // Post-action logic
    }
}

// Or use async version
public class CustomAsyncActionFilter : IAsyncActionFilter
{
    public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        // Pre-action logic
        var resultContext = await next();
        // Post-action logic
    }
}

Routing

ASP.NET MVC (Legacy)

// In RouteConfig.cs
routes.MapRoute(
    name: "Default",
    url: "{controller}/{action}/{id}",
    defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

.NET Core MVC

// In Startup.cs
app.UseRouting();
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "default",
        pattern: "{controller=Home}/{action=Index}/{id?}");
});

// Or use attribute routing
[Route("api/[controller]")]
public class ApiController : Controller
{
    [HttpGet("{id}")]
    public IActionResult Get(int id) { }
}

View Components (Replacement for Child Actions)

ASP.NET MVC (Legacy)

// Controller
[ChildActionOnly]
public ActionResult NavigationMenu()
{
    return PartialView(model);
}

// View
@Html.Action("NavigationMenu")

.NET Core MVC

// View Component
public class NavigationMenuViewComponent : ViewComponent
{
    public IViewComponentResult Invoke()
    {
        return View(model);
    }
}

// View
@await Component.InvokeAsync("NavigationMenu")

HTTP Context Access

ASP.NET MVC (Legacy)

// Direct access
HttpContext.Current.User
HttpContext.Current.Request.UserHostAddress

.NET Core MVC

// Inject IHttpContextAccessor
private readonly IHttpContextAccessor _httpContextAccessor;

public MyService(IHttpContextAccessor httpContextAccessor)
{
    _httpContextAccessor = httpContextAccessor;
}

// Usage
_httpContextAccessor.HttpContext.User
_httpContextAccessor.HttpContext.Connection.RemoteIpAddress

Session State

ASP.NET MVC (Legacy)

Session["Key"] = value;
var value = Session["Key"];

.NET Core MVC

// Configure in Startup.cs
services.AddDistributedMemoryCache();
services.AddSession();

// In controller
HttpContext.Session.SetString("Key", value);
var value = HttpContext.Session.GetString("Key");

Bundle Configuration

ASP.NET MVC (Legacy – BundleConfig.cs)

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
    "~/Scripts/jquery-{version}.js"));

bundles.Add(new StyleBundle("~/Content/css").Include(
    "~/Content/bootstrap.css",
    "~/Content/site.css"));

.NET Core MVC

<!-- Use LibMan, npm, or direct references -->
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />

<!-- Or use bundling libraries like WebOptimizer -->

Model Binding

ASP.NET MVC (Legacy)

public ActionResult Create(MyModel model)
{
    if (ModelState.IsValid)
    {
        // Process
        return RedirectToAction("Index");
    }
    return View(model);
}

.NET Core MVC

// Same pattern, but with async support
public async Task<IActionResult> Create(MyModel model)
{
    if (ModelState.IsValid)
    {
        // Process
        return RedirectToAction("Index");
    }
    return View(model);
}

// With explicit model binding
public IActionResult Create([FromForm] MyModel model) { }
public IActionResult Api([FromBody] MyModel model) { }

Authorization

ASP.NET MVC (Legacy)

[Authorize]
[Authorize(Roles = "Admin")]
public class AdminController : Controller { }

.NET Core MVC

// Same basic syntax, but with policy-based authorization
[Authorize]
[Authorize(Roles = "Admin")]
[Authorize(Policy = "RequireAdminRole")]
public class AdminController : Controller { }

// Configure policies in Startup.cs
services.AddAuthorization(options =>
{
    options.AddPolicy("RequireAdminRole", policy =>
        policy.RequireRole("Admin"));
});

File Uploads

ASP.NET MVC (Legacy)

public ActionResult Upload(HttpPostedFileBase file)
{
    if (file != null && file.ContentLength > 0)
    {
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(Server.MapPath("~/uploads/"), fileName);
        file.SaveAs(path);
    }
    return RedirectToAction("Index");
}

.NET Core MVC

public async Task<IActionResult> Upload(IFormFile file)
{
    if (file != null && file.Length > 0)
    {
        var fileName = Path.GetFileName(file.FileName);
        var path = Path.Combine(_webHostEnvironment.WebRootPath, "uploads", fileName);
        
        using var stream = new FileStream(path, FileMode.Create);
        await file.CopyToAsync(stream);
    }
    return RedirectToAction("Index");
}

Key Migration Tips

  1. Async/Await: .NET Core heavily uses async patterns. Convert synchronous operations to async where possible.
  2. Nullable Reference Types: Enable nullable reference types and handle null checks properly.
  3. Using Statements: .NET Core uses using declarations instead of using blocks where appropriate.
  4. Configuration: Move from Web.config to appsettings.json and use IConfiguration.
  5. Dependency Injection: Use the built-in DI container instead of external ones.
  6. Tag Helpers: Prefer Tag Helpers over HTML Helpers for better IntelliSense and cleaner markup.
  7. View Components: Replace Child Actions with View Components.
  8. Middleware: Use middleware pipeline instead of HTTP modules and handlers.
  9. Host Environment: Use IWebHostEnvironment instead of Server.MapPath.
  10. HTTP Context: Inject IHttpContextAccessor instead of using HttpContext.Current.


Posted

in

by

Tags:

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *