eShopOnWeb
Sample ASP.NET Core 8.0 reference application, powered by Microsoft, demonstrating a layered application architecture with monolithic deployment model. Download the eBook PDF from docs folder.
Top Related Projects
ASP.NET Boilerplate - Web Application Framework
ASP.NET Core eCommerce software. nopCommerce is a free and open-source shopping cart.
Open source, headless, multi-tenant eCommerce platform built with .NET Core, MongoDB, AWS DocumentDB, Azure CosmosDB, Vue.js.
A modular, scalable and ultra-fast open-source all-in-one eCommerce platform built on ASP.NET Core 7
Virto Commerce B2B Innovation Platform
Open Source Point of Sale is a web based point of sale application written in PHP using CodeIgniter framework. It uses MySQL as the data back end and has a Bootstrap 3 based user interface.
Quick Overview
eShopOnWeb is a sample ASP.NET Core reference application demonstrating a layered application architecture with a monolithic deployment model. It showcases best practices in building a modern web application using .NET Core and C#, including patterns like Clean Architecture and CQRS.
Pros
- Comprehensive example of a real-world e-commerce application
- Demonstrates clean architecture principles and SOLID design
- Includes examples of unit testing and integration testing
- Regularly updated to use the latest .NET Core version and best practices
Cons
- May be overwhelming for beginners due to its complexity
- Focuses on monolithic architecture, which may not be suitable for all scenarios
- Limited coverage of some advanced topics like caching or message queues
- Some parts of the application might be over-engineered for educational purposes
Code Examples
- Catalog Item Entity:
public class CatalogItem : BaseEntity, IAggregateRoot
{
public string Name { get; private set; }
public string Description { get; private set; }
public decimal Price { get; private set; }
public string PictureUri { get; private set; }
public int CatalogTypeId { get; private set; }
public CatalogType CatalogType { get; private set; }
public int CatalogBrandId { get; private set; }
public CatalogBrand CatalogBrand { get; private set; }
public CatalogItem(string name, string description, decimal price, string pictureUri, int catalogTypeId, int catalogBrandId)
{
Name = name;
Description = description;
Price = price;
PictureUri = pictureUri;
CatalogTypeId = catalogTypeId;
CatalogBrandId = catalogBrandId;
}
}
- Catalog Service:
public class CatalogService : ICatalogService
{
private readonly IRepository<CatalogItem> _itemRepository;
public CatalogService(IRepository<CatalogItem> itemRepository)
{
_itemRepository = itemRepository;
}
public async Task<CatalogItem> GetById(int id)
{
return await _itemRepository.GetByIdAsync(id);
}
public async Task<IEnumerable<CatalogItem>> List()
{
return await _itemRepository.ListAsync();
}
}
- Catalog Controller:
[ApiController]
[Route("api/[controller]")]
public class CatalogController : ControllerBase
{
private readonly ICatalogService _catalogService;
public CatalogController(ICatalogService catalogService)
{
_catalogService = catalogService;
}
[HttpGet]
public async Task<ActionResult<IEnumerable<CatalogItem>>> List()
{
var items = await _catalogService.List();
return Ok(items);
}
[HttpGet("{id}")]
public async Task<ActionResult<CatalogItem>> GetById(int id)
{
var item = await _catalogService.GetById(id);
if (item == null) return NotFound();
return Ok(item);
}
}
Getting Started
-
Clone the repository:
git clone https://github.com/dotnet-architecture/eShopOnWeb.git
-
Navigate to the project directory:
cd eShopOnWeb/src/Web
-
Run the application:
dotnet run
-
Open a web browser and go to
https://localhost:5001
to view the application.
Competitor Comparisons
ASP.NET Boilerplate - Web Application Framework
Pros of aspnetboilerplate
- Comprehensive framework with built-in modules for common enterprise application features
- Supports multi-tenancy out of the box
- Extensive documentation and community support
Cons of aspnetboilerplate
- Steeper learning curve due to its complexity and extensive features
- May be overkill for smaller projects or simple applications
- Less flexibility in architectural choices due to its opinionated nature
Code Comparison
aspnetboilerplate:
[AbpAuthorize(PermissionNames.Pages_Tenants)]
public class TenantAppService : AsyncCrudAppService<Tenant, TenantDto, int, PagedTenantResultRequestDto, CreateTenantDto, TenantDto>, ITenantAppService
{
// Implementation
}
eShopOnWeb:
public class CatalogController : Controller
{
private readonly IMediator _mediator;
public CatalogController(IMediator mediator) => _mediator = mediator;
public async Task<IActionResult> Index(CatalogIndexViewModel viewModel)
{
// Implementation
}
}
The aspnetboilerplate example showcases its built-in multi-tenancy and authorization features, while eShopOnWeb demonstrates a simpler, more straightforward controller implementation using the mediator pattern.
ASP.NET Core eCommerce software. nopCommerce is a free and open-source shopping cart.
Pros of nopCommerce
- Full-featured, production-ready e-commerce solution
- Extensive plugin ecosystem and customization options
- Active community and regular updates
Cons of nopCommerce
- Steeper learning curve due to its complexity
- Potentially heavier resource usage for smaller projects
- Less focused on demonstrating architectural patterns
Code Comparison
eShopOnWeb (Catalog Controller):
public async Task<IActionResult> Index(CatalogIndexViewModel viewModel, int? brandId, int? typeId, int? page)
{
var itemsPage = await _catalogViewModelService.GetCatalogItems(page ?? 0, Constants.ITEMS_PER_PAGE, brandId, typeId);
viewModel.CatalogItems = itemsPage.Data;
viewModel.PaginationInfo = new PaginationInfoViewModel()
{
// ... pagination logic
};
return View(viewModel);
}
nopCommerce (Product Controller):
public virtual async Task<IActionResult> ProductDetails(int productId, int updatecartitemid = 0)
{
var product = await _productService.GetProductByIdAsync(productId);
if (product == null || product.Deleted)
return InvokeHttp404();
var model = await _productModelFactory.PrepareProductDetailsModelAsync(product, updatecartitemid);
return View(model);
}
Both repositories showcase different approaches to e-commerce architecture. eShopOnWeb focuses on demonstrating clean architecture and modern development practices, while nopCommerce provides a comprehensive, production-ready solution with more features but increased complexity.
Open source, headless, multi-tenant eCommerce platform built with .NET Core, MongoDB, AWS DocumentDB, Azure CosmosDB, Vue.js.
Pros of grandnode
- More comprehensive e-commerce solution with advanced features like multi-vendor support and marketplace functionality
- Highly customizable and extendable architecture
- Active community and regular updates
Cons of grandnode
- Steeper learning curve due to its complexity
- May be overkill for simpler e-commerce projects
- Less focus on educational purposes compared to eShopOnWeb
Code Comparison
eShopOnWeb (Catalog Controller):
public async Task<IActionResult> Index(CatalogIndexViewModel viewModel, int? pageId)
{
var itemsPage = await _catalogViewModelService.GetCatalogItems(pageId ?? 0, Constants.ITEMS_PER_PAGE, viewModel.BrandFilterApplied, viewModel.TypesFilterApplied);
viewModel.CatalogItems = itemsPage.Data;
viewModel.PaginationInfo = new PaginationInfoViewModel()
{
// Pagination logic
};
return View(viewModel);
}
grandnode (Product Controller):
public virtual async Task<IActionResult> ProductDetails(string productId, string attributes = "")
{
var product = await _productService.GetProductById(productId);
if (product == null || product.Deleted || !product.Published)
return RedirectToRoute("HomePage");
var model = await _productViewModelService.PrepareProductDetailsModel(product, attributes);
return View(model);
}
Both repositories use ASP.NET Core MVC, but grandnode's codebase is more extensive and complex, reflecting its broader feature set. eShopOnWeb focuses on simplicity and educational value, while grandnode prioritizes a full-featured e-commerce solution.
A modular, scalable and ultra-fast open-source all-in-one eCommerce platform built on ASP.NET Core 7
Pros of Smartstore
- More comprehensive e-commerce solution with advanced features like multi-store support and plugin system
- Actively maintained with frequent updates and a larger community
- Includes a fully-featured admin panel and storefront out of the box
Cons of Smartstore
- Steeper learning curve due to its complexity and extensive codebase
- May be overkill for simple e-commerce projects or learning purposes
- Less focus on demonstrating clean architecture patterns compared to eShopOnWeb
Code Comparison
Smartstore (Product entity):
public partial class Product : BaseEntity, ISoftDeletable, ITransient
{
public string Name { get; set; }
public string ShortDescription { get; set; }
public string FullDescription { get; set; }
public bool Published { get; set; }
// ... more properties and methods
}
eShopOnWeb (CatalogItem entity):
public class CatalogItem : BaseEntity
{
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string PictureUri { get; set; }
public int CatalogTypeId { get; set; }
public CatalogType CatalogType { get; set; }
public int CatalogBrandId { get; set; }
public CatalogBrand CatalogBrand { get; set; }
}
Virto Commerce B2B Innovation Platform
Pros of vc-platform
- More comprehensive e-commerce solution with advanced features like multi-store management and B2B capabilities
- Highly modular architecture allowing for easier customization and extension
- Active community with regular updates and contributions
Cons of vc-platform
- Steeper learning curve due to its complexity and extensive feature set
- Potentially higher resource requirements for hosting and maintenance
- Less beginner-friendly documentation compared to eShopOnWeb
Code Comparison
vc-platform (Startup.cs):
public void ConfigureServices(IServiceCollection services)
{
services.AddVirtoCommerce(Configuration);
services.AddSwagger();
services.AddMvc().AddVirtoCommerce();
}
eShopOnWeb (Startup.cs):
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<CatalogContext>(c => c.UseSqlServer(Configuration.GetConnectionString("CatalogConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>().AddEntityFrameworkStores<AppIdentityDbContext>().AddDefaultTokenProviders();
services.AddMvc();
}
The code comparison shows that vc-platform uses a more abstracted approach with its custom extension methods, while eShopOnWeb configures services more explicitly. This reflects the difference in complexity and modularity between the two projects.
Open Source Point of Sale is a web based point of sale application written in PHP using CodeIgniter framework. It uses MySQL as the data back end and has a Bootstrap 3 based user interface.
Pros of opensourcepos
- More focused on a specific use case (Point of Sale) compared to the broader e-commerce approach of eShopOnWeb
- Actively maintained with frequent updates and contributions from the community
- Includes features specific to physical retail environments, such as barcode scanning and receipt printing
Cons of opensourcepos
- Less comprehensive documentation and architectural guidance compared to eShopOnWeb
- Smaller community and fewer stars on GitHub, potentially indicating less widespread adoption
- Limited to PHP, while eShopOnWeb showcases modern .NET development practices
Code Comparison
opensourcepos (PHP):
public function get_info($item_id)
{
$this->db->from('items');
$this->db->join('suppliers', 'suppliers.person_id = items.supplier_id', 'left');
$this->db->where('item_id', $item_id);
$query = $this->db->get();
if ($query->num_rows() == 1) {
return $query->row();
} else {
//Get empty base parent object, as $item_id is NOT an item
$item_obj = new stdClass();
//Get all the fields from items table
foreach ($this->db->list_fields('items') as $field) {
$item_obj->$field = '';
}
return $item_obj;
}
}
eShopOnWeb (C#):
public async Task<CatalogItem> GetByIdAsync(int id)
{
var item = await _dbContext.CatalogItems
.Include(ci => ci.CatalogBrand)
.Include(ci => ci.CatalogType)
.FirstOrDefaultAsync(ci => ci.Id == id);
return item;
}
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Microsoft eShopOnWeb ASP.NET Core Reference Application
eShop sample applications have been updated and moved to https://github.com/dotnet/eShop. Active development will continue there. We also recommend the Reliable Web App patterns guidance for building web apps with enterprise app patterns.
Sample ASP.NET Core reference application, powered by Microsoft, demonstrating a single-process (monolithic) application architecture and deployment model. If you're new to .NET development, read the Getting Started for Beginners guide.
A list of Frequently Asked Questions about this repository can be found here.
Overview Video
Steve "ardalis" Smith recorded a live stream providing an overview of the eShopOnWeb reference app in October 2020.
eBook
This reference application is meant to support the free .PDF download ebook: Architecting Modern Web Applications with ASP.NET Core and Azure, updated to ASP.NET Core 8.0. Also available in ePub/mobi formats.
You can also read the book in online pages at the .NET docs here: https://docs.microsoft.com/dotnet/architecture/modern-web-apps-azure/
The eShopOnWeb sample is related to the eShopOnContainers sample application which, in that case, focuses on a microservices/containers-based application architecture. However, eShopOnWeb is much simpler in regards to its current functionality and focuses on traditional Web Application Development with a single deployment.
The goal for this sample is to demonstrate some of the principles and patterns described in the eBook. It is not meant to be an eCommerce reference application, and as such it does not implement many features that would be obvious and/or essential to a real eCommerce application.
VERSIONS
The
main
branch is currently running ASP.NET Core 8.0.Older versions are tagged.
Topics (eBook TOC)
- Introduction
- Characteristics of Modern Web Applications
- Choosing Between Traditional Web Apps and SPAs
- Architectural Principles
- Common Web Application Architectures
- Common Client Side Technologies
- Developing ASP.NET Core MVC Apps
- Working with Data in ASP.NET Core Apps
- Testing ASP.NET Core MVC Apps
- Development Process for Azure-Hosted ASP.NET Core Apps
- Azure Hosting Recommendations for ASP.NET Core Web Apps
Running the sample using Azd template
The store's home page should look like this:
The Azure Developer CLI (azd
) is a developer-centric command-line interface (CLI) tool for creating Azure applications.
You need to install it before running and deploying with Azure Developer CLI.
Windows
powershell -ex AllSigned -c "Invoke-RestMethod 'https://aka.ms/install-azd.ps1' | Invoke-Expression"
Linux/MacOS
curl -fsSL https://aka.ms/install-azd.sh | bash
And you can also install with package managers, like winget, choco, and brew. For more details, you can follow the documentation: https://aka.ms/azure-dev/install.
After logging in with the following command, you will be able to use the azd cli to quickly provision and deploy the application.
azd auth login
Then, execute the azd init
command to initialize the environment.
azd init -t dotnet-architecture/eShopOnWeb
Run azd up
to provision all the resources to Azure and deploy the code to those resources.
azd up
According to the prompt, enter an env name
, and select subscription
and location
, these are the necessary parameters when you create resources. Wait a moment for the resource deployment to complete, click the web endpoint and you will see the home page.
Notes:
- Considering security, we store its related data (id, password) in the Azure Key Vault when we create the database, and obtain it from the Key Vault when we use it. This is different from directly deploying applications locally.
- The resource group name created in azure portal will be rg-{env name}.
You can also run the sample directly locally (See below).
Running the sample locally
Most of the site's functionality works with just the web application running. However, the site's Admin page relies on Blazor WebAssembly running in the browser, and it must communicate with the server using the site's PublicApi web application. You'll need to also run this project. You can configure Visual Studio to start multiple projects, or just go to the PublicApi folder in a terminal window and run dotnet run
from there. After that from the Web folder you should run dotnet run --launch-profile Web
. Now you should be able to browse to https://localhost:5001/
. The admin part in Blazor is accessible to https://localhost:5001/admin
Note that if you use this approach, you'll need to stop the application manually in order to build the solution (otherwise you'll get file locking errors).
After cloning or downloading the sample you must setup your database. To use the sample with a persistent database, you will need to run its Entity Framework Core migrations before you will be able to run the app.
You can also run the samples in Docker (see below).
Configuring the sample to use SQL Server
-
By default, the project uses a real database. If you want an in memory database, you can add in the
appsettings.json
file in the Web folder{ "UseOnlyInMemoryDatabase": true }
-
Ensure your connection strings in
appsettings.json
point to a local SQL Server instance. -
Ensure the tool EF was already installed. You can find some help here
dotnet tool update --global dotnet-ef
-
Open a command prompt in the Web folder and execute the following commands:
dotnet restore dotnet tool restore dotnet ef database update -c catalogcontext -p ../Infrastructure/Infrastructure.csproj -s Web.csproj dotnet ef database update -c appidentitydbcontext -p ../Infrastructure/Infrastructure.csproj -s Web.csproj
These commands will create two separate databases, one for the store's catalog data and shopping cart information, and one for the app's user credentials and identity data.
-
Run the application.
The first time you run the application, it will seed both databases with data such that you should see products in the store, and you should be able to log in using the demouser@microsoft.com account.
Note: If you need to create migrations, you can use these commands:
-- create migration (from Web folder CLI) dotnet ef migrations add InitialModel --context catalogcontext -p ../Infrastructure/Infrastructure.csproj -s Web.csproj -o Data/Migrations dotnet ef migrations add InitialIdentityModel --context appidentitydbcontext -p ../Infrastructure/Infrastructure.csproj -s Web.csproj -o Identity/Migrations
Running the sample in the dev container
This project includes a .devcontainer
folder with a dev container configuration, which lets you use a container as a full-featured dev environment.
You can use the dev container to build and run the app without needing to install any of its tools locally! You can work in GitHub Codespaces or the VS Code Dev Containers extension.
Learn more about using the dev container in its readme.
Running the sample using Docker
You can run the Web sample by running these commands from the root folder (where the .sln file is located):
docker-compose build
docker-compose up
You should be able to make requests to localhost:5106 for the Web project, and localhost:5200 for the Public API project once these commands complete. If you have any problems, especially with login, try from a new guest or incognito browser instance.
You can also run the applications by using the instructions located in their Dockerfile
file in the root of each project. Again, run these commands from the root of the solution (where the .sln file is located).
Community Extensions
We have some great contributions from the community, and while these aren't maintained by Microsoft we still want to highlight them.
eShopOnWeb VB.NET by Mohammad Hamdy Ghanem
FShopOnWeb An F# take on eShopOnWeb by Sean G. Wright and Kyle McMaster
Top Related Projects
ASP.NET Boilerplate - Web Application Framework
ASP.NET Core eCommerce software. nopCommerce is a free and open-source shopping cart.
Open source, headless, multi-tenant eCommerce platform built with .NET Core, MongoDB, AWS DocumentDB, Azure CosmosDB, Vue.js.
A modular, scalable and ultra-fast open-source all-in-one eCommerce platform built on ASP.NET Core 7
Virto Commerce B2B Innovation Platform
Open Source Point of Sale is a web based point of sale application written in PHP using CodeIgniter framework. It uses MySQL as the data back end and has a Bootstrap 3 based user interface.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot