Unit 6: Asp.Net With Web API

INT402 — Modern Web Programming Tools And Techniques 9 min read

I. Foundations of Web APIs

REST and Web APIs support communication between clients and servers through standard HTTP operations. REST (Representational State Transfer, introduced by Roy Fielding in 2000) provides architectural constraints, while ASP.NET Web API supplies the Microsoft framework components needed to implement HTTP services.

Defining characteristics:

  • Resource orientation: Business entities such as customers, products, or orders are represented as addressable resources.
  • HTTP communication: Clients send HTTP requests, and servers return HTTP responses.
  • Standard methods: GET, POST, PUT, PATCH, and DELETE express operations on resources.
  • Representations: Resources are commonly exchanged as JSON or XML.
  • Statelessness: Each request contains all information necessary for the server to process it.
  • Client independence: Browsers, mobile applications, desktop programs, and other services can use the same API.
  • Uniform interface: Predictable URIs, methods, headers, and status codes simplify integration.

A. Introduction to REST

REST is an architectural style in which a server exposes resources through URIs and clients manipulate their representations using HTTP.

  • Resource: A resource is a named entity, such as a product identified by /api/products/5.
  • URI design: URIs normally use nouns rather than operation names.
    • Preferred: /api/products/5
    • Avoid: /api/getProduct?id=5
  • HTTP methods: Each method has a conventional purpose.
    • GET /api/products: retrieves all products.
    • GET /api/products/5: retrieves product 5.
    • POST /api/products: creates a product.
    • PUT /api/products/5: replaces or fully updates product 5.
    • PATCH /api/products/5: partially updates product 5.
    • DELETE /api/products/5: removes product 5.
  • Stateless requests: Authentication credentials, parameters, and content needed for one operation must accompany that request; the server should not depend on a previous request.
  • Representations: A product may be transferred as JSON:
JSON
{
  "id": 5,
  "name": "Keyboard",
  "price": 1200.00
}
  • Status codes: HTTP codes communicate results consistently.
    • 200 OK: successful retrieval or update.
    • 201 Created: resource successfully created.
    • 204 No Content: successful operation with no response body.
    • 400 Bad Request: invalid client input.
    • 404 Not Found: requested resource does not exist.
    • 500 Internal Server Error: unexpected server-side failure.
  • REST advantage: The separation between client interface and server implementation permits both sides to evolve independently.
  • REST limitation: A poorly designed API may misuse methods, expose inconsistent URIs, or return inappropriate status codes even though it communicates through HTTP.

II. ASP.NET Web API Development

ASP.NET Web API is a Microsoft framework for building HTTP services on the .NET platform. The following discussion uses the ASP.NET Web API 2 model, where controllers inherit from ApiController.

A. Introduction to ASP.NET Web API

ASP.NET Web API converts HTTP requests into controller method calls and serializes returned data into response representations.

  • Controller: An API controller inherits from System.Web.Http.ApiController.
CSHARP
public class ProductsController : ApiController
{
    public IHttpActionResult Get()
    {
        return Ok(new[] { "Mouse", "Keyboard" });
    }
}
  • Action selection: The framework selects methods through HTTP method names, attributes, route values, and parameters.
  • Content negotiation: The server chooses a representation according to the request and available formatters, commonly returning JSON for application/json.
  • Model binding: Route values, query-string values, and request-body content are converted into C# parameters or objects.
  • Response construction: IHttpActionResult methods such as Ok(), NotFound(), and BadRequest() produce meaningful HTTP responses.
  • Web API versus MVC: MVC controllers primarily return HTML views, whereas Web API controllers return resource data and HTTP responses.
  • Cross-platform clients: Any client capable of HTTP communication can consume the service; it does not need to use .NET.

B. Building ASP.NET Web API

Building an API involves defining models, controllers, routes, persistence logic, and correctly formed HTTP responses.

  • Model definition: A model describes the data transferred or stored.
CSHARP
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
}
  • Controller creation: A controller groups operations for one resource, such as ProductsController.
  • Action mapping: Method attributes explicitly identify HTTP operations.
CSHARP
[HttpGet]
public IHttpActionResult GetProduct(int id)
{
    Product product = repository.Find(id);
    return product == null ? NotFound() : Ok(product);
}
  • Validation: Data annotations define input rules.
CSHARP
[Required]
[StringLength(100)]
public string Name { get; set; }
  • Invalid models: ModelState.IsValid should be checked before database modification; invalid input should produce 400 Bad Request.
  • Dependency separation: Data-access logic should be placed in a repository or service rather than embedded extensively in controllers.
  • Security considerations: Production APIs commonly require HTTPS, authentication, authorization, controlled cross-origin access, and protection of sensitive fields.
  • Error handling: Expected conditions should return specific status codes, while global exception handling should prevent internal implementation details from leaking.

C. Creating First Web API Project

A first Web API project establishes the application structure and verifies that an HTTP endpoint is reachable.

  • Project setup: In Visual Studio, create an ASP.NET Web Application (.NET Framework) and select the Web API template.
  • Important folders: A typical project contains:
    • Controllers: API controller classes.
    • Models: domain or data-transfer classes.
    • App_Start: route and configuration classes.
    • Global.asax: application startup code.
  • Configuration registration: Global.asax calls Web API configuration during startup.
CSHARP
protected void Application_Start()
{
    GlobalConfiguration.Configure(WebApiConfig.Register);
}
  • First controller: A simple endpoint can return a fixed message.
CSHARP
public class HelloController : ApiController
{
    public IHttpActionResult Get()
    {
        return Ok("Hello Web API");
    }
}
  • Execution: Running the project and requesting /api/hello invokes HelloController.Get().
  • Observed response: A successful request produces status 200 OK and a JSON-formatted string.
  • Project principle: Initial testing with fixed data isolates configuration and routing from later database-related problems.

III. Data Storage and Resource Operations

A database-backed API persists resource state beyond a single application execution. Entity Framework can map C# model objects to relational database tables and generate SQL operations.

A. Creating Database for Web API

Creating the database requires a schema, a connection string, and a data-access context linking the application to stored records.

  • Table structure: A Products table may contain Id, Name, and Price.
SQL
CREATE TABLE Products (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(100) NOT NULL,
    Price DECIMAL(10,2) NOT NULL
);
  • Column meaning: Id is an automatically generated primary key; Name stores up to 100 Unicode characters; Price stores two decimal places.
  • Connection string: The application stores database connection information in Web.config.
XML
<connectionStrings>
  <add name="StoreDb"
       connectionString="Data Source=(localdb)\MSSQLLocalDB;
       Initial Catalog=StoreDb;Integrated Security=True"
       providerName="System.Data.SqlClient" />
</connectionStrings>
  • Entity Framework context: DbContext represents a database session, while DbSet<Product> represents the product collection.
CSHARP
public class StoreContext : DbContext
{
    public StoreContext() : base("StoreDb") { }
    public DbSet<Product> Products { get; set; }
}
  • Database-first approach: Classes can be generated from an existing database schema.
  • Code-first approach: The schema is created or changed from C# entity classes and migrations.
  • Migration role: Commands such as Add-Migration InitialCreate and Update-Database record and apply schema changes.
  • Data integrity: Primary keys, non-null constraints, appropriate data types, and validation prevent inconsistent records.

B. ASP.NET Web API CRUD Operations

CRUD represents the four fundamental persistence operations: Create, Read, Update, and Delete.

  1. Create and Read
    • Create: POST accepts a product, inserts it, and returns 201 Created.
CSHARP
[HttpPost]
public IHttpActionResult Post(Product product)
{
    if (!ModelState.IsValid)
        return BadRequest(ModelState);

    db.Products.Add(product);
    db.SaveChanges();

    return CreatedAtRoute(
        "DefaultApi",
        new { id = product.Id },
        product);
}
  • Read collection: GET /api/products returns db.Products.ToList().
  • Read one: GET /api/products/5 searches by key and returns either 200 OK or 404 Not Found.
  1. Update and Delete
    • Update: PUT /api/products/5 verifies that the route identifier matches the supplied object, marks it modified, and calls SaveChanges().
    • Delete: DELETE /api/products/5 locates the record, removes it, and persists the change.
CSHARP
[HttpDelete]
public IHttpActionResult Delete(int id)
{
    Product product = db.Products.Find(id);

    if (product == null)
        return NotFound();

    db.Products.Remove(product);
    db.SaveChanges();
    return Ok(product);
}
  • Atomic persistence: SaveChanges() sends pending entity changes to the database, normally within a transaction.
  • Concurrency: Simultaneous updates may overwrite data; timestamps or row-version columns can detect conflicting modifications.
  • DTO usage: Data-transfer objects prevent clients from changing protected database fields and avoid exposing internal entity structure.

IV. API Verification

Testing confirms that endpoints accept the intended inputs and return correct content, headers, status codes, and error responses.

A. Testing Web API Using Postman

Postman is an HTTP client used to construct requests and inspect API responses without developing a separate front-end application.

  • Request URL: Enter the complete endpoint, such as https://localhost:44300/api/products.
  • Method selection: Choose GET, POST, PUT, or DELETE from the request-method list.
  • Headers: For JSON input, send:
HTTP
Content-Type: application/json
Accept: application/json
  • POST body: Select Body → raw → JSON and provide valid data.
JSON
{
  "name": "Web Camera",
  "price": 2499.00
}
  • Response inspection: Verify the status code, response time, headers, and JSON body. A successful creation should normally return 201 Created.
  • CRUD sequence: Create a product, note its generated id, retrieve it, update it, delete it, and confirm that a later retrieval returns 404 Not Found.
  • Negative testing: Send missing fields, malformed JSON, invalid identifiers, and duplicate values where relevant.
  • Authentication testing: Protected APIs may require an Authorization header, often carrying a bearer token.
  • Environment variables: Values such as {{baseUrl}} allow the same request collection to target development or production servers.

V. Request Routing

Routing maps an incoming URI and HTTP method to a controller action. ASP.NET Web API supports centralized convention-based routes and route templates declared directly on controllers or actions.

A. Routing: Convention and Attribute Routing

Convention routing follows a shared route template, whereas attribute routing gives individual actions explicit URI patterns.

  1. Convention routing
    • Configuration: Routes are registered centrally in WebApiConfig.cs.
CSHARP
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional }
);
  • Resolution: /api/products/5 maps products to ProductsController and supplies 5 as the id parameter.
  • Strength: A single pattern gives consistent resource URLs with little configuration.
  • Limitation: Complex hierarchical or action-specific URLs may be difficult to represent clearly.
  1. Attribute routing
    • Activation: Attribute routing is enabled during configuration.
CSHARP
config.MapHttpAttributeRoutes();
  • Declaration: Route templates are attached to controllers and methods.
CSHARP
[RoutePrefix("api/products")]
public class ProductsController : ApiController
{
    [HttpGet]
    [Route("{id:int}")]
    public IHttpActionResult Get(int id)
    {
        return Ok(id);
    }
}
  • Constraint: {id:int} matches only an integer route segment, so /api/products/10 matches but /api/products/abc does not.
  • Custom path: An action may use [Route("category/{name}")] to support /api/products/category/electronics.
  • Strength: Routes remain close to their actions and can express constraints, optional segments, prefixes, and nested paths.
  • Limitation: Numerous unrelated attributes can make route design inconsistent unless naming conventions are enforced.
    • Route precedence: More specific attribute routes should be designed to avoid conflicts with general templates.
    • Parameter sources: Simple values commonly come from URI segments or query strings, while complex objects normally come from the request body.