ASP.NET MVC 5 and Web API are commonly used for creating robust and scalable web applications and APIs. Below, I provide best practices along with a real-time example to help structure your Web API application effectively.
1. Folder Structure
Organize your project into logical folders:
- Models: For data models.
- ViewModels: For presentation-specific models.
- Controllers: For API controllers.
- Repositories: For data access logic.
- Services: For business logic.
- DTOs: For Data Transfer Objects.
- Utilities: For helpers and utilities.
2. Use Dependency Injection
Use a DI container like Unity or Ninject to manage dependencies.
Install Unity:
Install-Package Unity.Mvc
Register Unity in App_Start
folder:
{
public static void RegisterComponents()
{
var container = new UnityContainer();
// Register dependencies
container.RegisterType<IProductService, ProductService>();
container.RegisterType<IProductRepository, ProductRepository>();
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}
}
3. Use DTOs
Separate API models from database models to prevent over-posting attacks and reduce tight coupling.
4. Implement Repository and Unit of Work Pattern
Repository: Encapsulates data access logic.
Unit of Work: Manages transactions.
Real-Time Example: A Product API
Step 1: Models
Product.cs
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public bool IsAvailable { get; set; }
}
Step 2: DTOs
ProductDTO.cs
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
Step 3: Repository
IProductRepository.cs
{
IEnumerable<Product> GetAll();
Product GetById(int id);
void Add(Product product);
void Update(Product product);
void Delete(int id);
}
ProductRepository.cs
{
private readonly AppDbContext _context;
public ProductRepository(AppDbContext context)
{ _context = context;
}
public IEnumerable<Product> GetAll() => _context.Products.ToList();
public Product GetById(int id) => _context.Products.Find(id);
public void Add(Product product)
{
_context.Products.Add(product);
_context.SaveChanges();
}
public void Update(Product product)
{
_context.Entry(product).State = EntityState.Modified;
_context.SaveChanges();
}
public void Delete(int id)
{
var product = _context.Products.Find(id);
if (product != null)
{
_context.Products.Remove(product);
_context.SaveChanges();
}
}
}
Step 4: Service Layer
IProductService.cs
{
IEnumerable<ProductDTO> GetProducts();
ProductDTO GetProductById(int id);
void CreateProduct(ProductDTO productDto);
void UpdateProduct(ProductDTO productDto);
void DeleteProduct(int id);
}
ProductService.cs
{
private readonly IProductRepository _productRepository;
public ProductService(IProductRepository productRepository)
{
_productRepository = productRepository;
}
public IEnumerable<ProductDTO> GetProducts()
{
return _productRepository.GetAll() .Select(p => new ProductDTO { Id = p.Id, Name = p.Name, Price = p.Price });
}
public ProductDTO GetProductById(int id)
{
var product = _productRepository.GetById(id);
if (product == null)
return null;
return new ProductDTO { Id = product.Id, Name = product.Name, Price = product.Price };
}
public void CreateProduct(ProductDTO productDto)
{
var product = new Product { Name = productDto.Name, Price = productDto.Price, IsAvailable = true };
_productRepository.Add(product);
}
public void UpdateProduct(ProductDTO productDto)
{
var product = _productRepository.GetById(productDto.Id);
if (product != null)
{ product.Name = productDto.Name; product.Price = productDto.Price;
_productRepository.Update(product);
}
}
public void DeleteProduct(int id)
{
_productRepository.Delete(id);
}
}
Step 5: Controller
ProductsController.cs
public class ProductsController : ApiController
{
private readonly IProductService _productService;
public ProductsController(IProductService productService)
{
_productService = productService;
}
[ ] [ ]
public IHttpActionResult GetProducts()
{
var products = _productService.GetProducts();
return Ok(products);
}
[ ] [ ]
public IHttpActionResult GetProduct(int id)
{
var product = _productService.GetProductById(id);
if (product == null)
return NotFound();
return Ok(product);
}
[ ]
[ ]
public IHttpActionResult CreateProduct(ProductDTO productDto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
_productService.CreateProduct(productDto);
return Created("", productDto);
}
[ ] [ ]
public IHttpActionResult UpdateProduct(int id, ProductDTO productDto)
{
if (!ModelState.IsValid)
return BadRequest(ModelState);
productDto.Id = id;
_productService.UpdateProduct(productDto);
return Ok();
}
[ ]
[ ]
public IHttpActionResult DeleteProduct(int id)
{
_productService.DeleteProduct(id);
return Ok();
}
}
Step 6: Enable CORS (If Needed)
Add CORS support in WebApiConfig.cs
:
Step 7: Test with Swagger
Install Swashbuckle for Swagger support:
Install-Package Swashbuckle
Configure in App_Start
:
This approach ensures clean, modular, and scalable Web API development using ASP.NET MVC 5.