.agents/skills/migrate-aspnetboilerplate-to-abp/SKILL.md
Migrate existing ASP.NET Boilerplate projects to ABP.IO framework with step-by-step guidance, code transformation, and best practices.
npx skillsauth add afonsoft/VideoChat migrate-aspnetboilerplate-to-abpInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Migrate existing ASP.NET Boilerplate projects to the modern ABP.IO framework with comprehensive guidance and automated transformation steps.
Your goal is to guide the migration of an existing ASP.NET Boilerplate project to ABP.IO framework, ensuring minimal disruption and maximum compatibility.
Before starting migration, verify:
Good Candidates for Migration:
Challenging Migrations:
# Install ABP CLI
dotnet tool install -g Volo.Abp.Cli
# Verify installation
abp --version
# Create complete backup
cp -r MyProject MyProject_backup_$(date +%Y%m%d)
# Git tag current state
git tag aspnetboilerplate_final
git push origin aspnetboilerplate_final
Create dependency inventory:
# List current packages
dotnet list package
# Analyze third-party dependencies
# Document custom modifications
# Note breaking changes needed
Based on project analysis, select appropriate ABP template:
# For standard web applications
abp new MyCompany.MyProject -t app -u mvc -d ef
# For applications with Angular
abp new MyCompany.MyProject -t app -u angular -d ef --tiered
# For simple applications
abp new MyCompany.MyProject -t app-nolayers -u mvc -d ef
# Navigate to new project
cd MyCompany.MyProject
# Restore packages
dotnet restore
# Create initial database
dotnet ef database update
# Run application to verify
dotnet run --project src/MyCompany.MyProject.Web
Entity Migration Pattern:
// ASP.NET Boilerplate Entity
public class Product : FullAuditedEntity
{
public string Name { get; set; }
public decimal Price { get; set; }
public ProductCategory Category { get; set; }
}
// ABP Entity
public class Product : FullAuditedAggregateRoot<Guid>
{
public string Name { get; set; }
public decimal Price { get; set; }
public ProductCategory Category { get; set; }
protected Product() { }
public Product(
Guid id,
string name,
decimal price,
ProductCategory category) : base(id)
{
Name = Check.NotNullOrWhiteSpace(name, nameof(name));
Price = price;
Category = category;
}
}
Value Object Migration:
// ASP.NET Boilerplate
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string Country { get; set; }
}
// ABP Value Object
public class Address : ValueObject
{
public string Street { get; set; }
public string City { get; set; }
public string Country { get; set; }
protected override IEnumerable<object> GetEqualityComponents()
{
yield return Street;
yield return City;
yield return Country;
}
}
Repository Migration:
// ASP.NET Boilerplate Repository Interface
public interface IProductRepository : IRepository<Product>
{
List<Product> GetProductsByCategory(int categoryId);
}
// ABP Repository Interface
public interface IProductRepository : IRepository<Product, Guid>
{
Task<List<Product>> GetProductsByCategoryAsync(Guid categoryId);
}
Application Service Migration:
// ASP.NET Boilerplate Application Service
public class ProductAppService : ApplicationService, IProductAppService
{
private readonly IRepository<Product> _productRepository;
public ProductAppService(IRepository<Product> productRepository)
{
_productRepository = productRepository;
}
public ListResultDto<ProductDto> GetAll(GetAllProductsInput input)
{
var products = _productRepository.GetAllList();
return new ListResultDto<ProductDto>(
ObjectMapper.Map<List<Product>, List<ProductDto>>(products)
);
}
}
// ABP Application Service
public class ProductAppService : ApplicationService, IProductAppService
{
private readonly IRepository<Product, Guid> _productRepository;
public ProductAppService(IRepository<Product, Guid> productRepository)
{
_productRepository = productRepository;
}
public async Task<PagedResultDto<ProductDto>> GetListAsync(GetProductsInput input)
{
var queryable = await _productRepository.GetQueryableAsync();
var products = await AsyncExecuter.ToListAsync(
queryable
.WhereIf(!input.Filter.IsNullOrWhiteSpace(),
p => p.Name.Contains(input.Filter))
.OrderBy(p => p.Name)
.PageBy(input.SkipCount, input.MaxResultCount)
);
var totalCount = await AsyncExecuter.CountAsync(
queryable.WhereIf(!input.Filter.IsNullOrWhiteSpace(),
p => p.Name.Contains(input.Filter))
);
return new PagedResultDto<ProductDto>(
totalCount,
ObjectMapper.Map<List<Product>, List<ProductDto>>(products)
);
}
}
DTO Migration:
// ASP.NET Boilerplate DTO
public class ProductDto : EntityDto
{
public string Name { get; set; }
public decimal Price { get; set; }
}
// ABP DTO
public class ProductDto : EntityDto<Guid>
{
public string Name { get; set; }
public decimal Price { get; set; }
}
public class CreateUpdateProductDto
{
[Required]
[StringLength(ProductConsts.MaxNameLength)]
public string Name { get; set; }
[Range(0.01, 10000.00)]
public decimal Price { get; set; }
}
Entity Framework Configuration:
// ASP.NET Boilerplate Configuration
public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> builder)
{
builder.ToTable("Products");
builder.Property(p => p.Name)
.IsRequired()
.HasMaxLength(128);
builder.Property(p => p.Price)
.HasColumnType("decimal(18,2)");
}
}
// ABP Configuration (similar but with updated namespaces)
public class ProductConfiguration : IEntityTypeConfiguration<Product>
{
public void Configure(EntityTypeBuilder<Product> builder)
{
builder.ToTable(MyProjectConsts.DbTablePrefix + "Products", MyProjectConsts.DbSchema);
builder.Property(x => x.Name)
.IsRequired()
.HasMaxLength(ProductConsts.MaxNameLength);
builder.Property(x => x.Price)
.HasColumnType("decimal(18,2)");
}
}
Controller Migration:
// ASP.NET Boilerplate Controller
public class ProductsController : AbpController
{
private readonly IProductAppService _productAppService;
public ProductsController(IProductAppService productAppService)
{
_productAppService = productAppService;
}
public ActionResult Index()
{
var products = _productAppService.GetAll(new GetAllProductsInput());
return View(products);
}
}
// ABP Controller
public class ProductsController : AbpControllerBase
{
private readonly IProductAppService _productAppService;
public ProductsController(IProductAppService productAppService)
{
_productAppService = productAppService;
}
public async Task<IActionResult> Index()
{
var products = await _productAppService.GetListAsync(new GetProductsInput());
return View(products);
}
}
// ASP.NET Boilerplate namespaces
using Abp.Application.Services;
using Abp.Domain.Repositories;
using Abp.Authorization;
using Abp.UI;
using Abp.Domain.Entities;
using Abp.EntityFrameworkCore;
using Abp.AspNetCore.Mvc.Controllers;
// ABP namespaces
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Authorization;
using Volo.Abp;
using Volo.Abp.Domain.Entities;
using Volo.Abp.EntityFrameworkCore;
using Volo.Abp.AspNetCore.Mvc;
<!-- ASP.NET Boilerplate packages -->
<PackageReference Include="Abp.AspNetCore" Version="6.4.0" />
<PackageReference Include="Abp.EntityFrameworkCore" Version="6.4.0" />
<PackageReference Include="Abp.AspNetCore.Mvc" Version="6.4.0" />
<!-- ABP packages -->
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="8.0.0" />
<PackageReference Include="Volo.Abp.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Volo.Abp.AspNetCore" Version="8.0.0" />
// ASP.NET Boilerplate Module
[DependsOn(typeof(AbpAspNetCoreModule))]
public class MyProjectWebModule : AbpModule
{
public override void Initialize()
{
IocManager.RegisterAssemblyByConvention(typeof(MyProjectWebModule));
}
}
// ABP Module
[DependsOn(
typeof(MyProjectApplicationModule),
typeof(MyProjectEntityFrameworkCoreModule),
typeof(AbpAspNetCoreMvcModule)
)]
public class MyProjectWebModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpAspNetCoreMvcOptions>(options =>
{
options.ConventionalControllers.Create(typeof(MyProjectApplicationModule).Assembly);
});
}
}
// ASP.NET Boilerplate appsettings.json
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyProjectDb;Trusted_Connection=true"
}
}
// ABP appsettings.json
{
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyProjectDb;Trusted_Connection=true"
},
"App": {
"SelfUrl": "https://localhost:44300",
"CorsOrigins": "https://localhost:44300"
},
"AuthServer": {
"Authority": "https://localhost:44300",
"RequireHttpsMetadata": "false"
}
}
// ASP.NET Boilerplate Test
public class ProductAppService_Tests : AppTestBase
{
private readonly IProductAppService _productAppService;
public ProductAppService_Tests()
{
_productAppService = Resolve<IProductAppService>();
}
[Fact]
public void Should_Get_All_Products()
{
var products = _productAppService.GetAll(new GetAllProductsInput());
products.Items.Count.ShouldBeGreaterThan(0);
}
}
// ABP Test
public class ProductAppService_Tests : MyProjectApplicationTestBase
{
private readonly IProductAppService _productAppService;
public ProductAppService_Tests()
{
_productAppService = GetRequiredService<IProductAppService>();
}
[Fact]
public async Task Should_Get_All_Products()
{
var products = await _productAppService.GetListAsync(new GetProductsInput());
products.TotalCount.ShouldBeGreaterThan(0);
}
}
# Run all tests
dotnet test
# Check database migrations
dotnet ef migrations list
# Verify application startup
dotnet run --project src/MyCompany.MyProject.Web
#!/bin/bash
# migrate-to-abp.sh
PROJECT_NAME=$1
TEMPLATE_TYPE=${2:-"app"}
UI_FRAMEWORK=${3:-"mvc"}
DB_PROVIDER=${4:-"ef"}
echo "Migrating $PROJECT_NAME to ABP.IO..."
# Create new ABP project
abp new $PROJECT_NAME -t $TEMPLATE_TYPE -u $UI_FRAMEWORK -d $DB_PROVIDER
# Copy domain entities
echo "Copying domain entities..."
cp -r ../$PROJECT_NAME_backup/src/$PROJECT_NAME.Domain/Entities src/$PROJECT_NAME.Domain/
# Copy application services (with manual conversion needed)
echo "Preparing application services..."
mkdir -p src/$PROJECT_NAME.Application/Services
# Update package references
echo "Updating package references..."
find . -name "*.csproj" -exec sed -i 's/Abp\./Volo.Abp./g' {} \;
# Run initial setup
echo "Running initial setup..."
cd $PROJECT_NAME
dotnet restore
dotnet ef database update
echo "Migration setup complete! Manual conversion required for:"
echo "1. Application services"
echo "2. Controllers"
echo "3. Views/UI components"
echo "4. Configuration files"
echo "5. Custom business logic"
Problem: Ambiguous references between old and new ABP namespaces Solution: Use fully qualified names or alias directives
using OldAbp = Abp;
using NewAbp = Volo.Abp;
Problem: ABP uses Guid keys by default
Solution: Update entities to use Guid keys or configure custom keys
public class Product : FullAuditedAggregateRoot<int> // Use int instead of Guid
{
// Entity definition
}
Problem: ABP requires async patterns for repository operations Solution: Update all repository calls to async
// Before
var products = _repository.GetAllList();
// After
var products = await _repository.GetListAsync();
Problem: Authorization attributes have different names Solution: Update attribute references
// Before
[AbpAuthorize("Products.Create")]
// After
[Authorize("Products.Create")]
This migration guide provides comprehensive steps to successfully transition from ASP.NET Boilerplate to ABP.IO while maintaining functionality and improving code quality.
development
This skill enables visual inspection of websites running locally or remotely to identify and fix design issues. Triggers on requests like "review website design", "check the UI", "fix the layout", "find design problems". Detects issues with responsive design, accessibility, visual consistency, and layout breakage, then performs fixes at the source code level.
testing
Comprehensive unit testing with xUnit, mocking, test patterns, and best practices for .NET applications
data-ai
Universal SQL performance optimization assistant for comprehensive query tuning, indexing strategies, and database performance analysis across all SQL databases (MySQL, PostgreSQL, SQL Server, Oracle). Provides execution plan analysis, pagination optimization, batch operations, and performance monitoring guidance.
development
Universal SQL code review assistant that performs comprehensive security, maintainability, and code quality analysis across all SQL databases (MySQL, PostgreSQL, SQL Server, Oracle). Focuses on SQL injection prevention, access control, code standards, and anti-pattern detection. Complements SQL optimization prompt for complete development coverage.