← Back to Articles         
Sending JSON from Angular to Web API

Sending JSON from Angular to Web API

Published on 01 Oct 2026     9 min read Angular
HTTP & Web API Integration

Sending JSON from Angular to ASP.NET Core and Deserializing into a DTO

These two questions describe the two sides of the same HTTP request:

Angular
   ↓
TypeScript object
   ↓
HttpClient.post()
   ↓
JSON request body
   ↓
ASP.NET Core Web API
   ↓
Model Binding + JSON Deserialization
   ↓
C# DTO

Full Simple Sample Program

We will send this product from Angular:

{
  "name": "Laptop",
  "price": 75000
}

ASP.NET Core will receive it as:

CreateProductDto

Angular — product.ts

export interface CreateProduct {
  name: string;
  price: number;
}

Angular — product.service.ts

import { inject, Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

import { CreateProduct } from './product';

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  private http = inject(HttpClient);

  private apiUrl =
    'https://localhost:7001/api/products';

  addProduct(
    product: CreateProduct
  ): Observable<CreateProduct> {

    return this.http.post<CreateProduct>(
      this.apiUrl,
      product
    );
  }
}

Angular — Component

import { Component, inject } from '@angular/core';

import { ProductService } from './product.service';
import { CreateProduct } from './product';

@Component({
  selector: 'app-products',
  standalone: true,
  template: `
    <button (click)="addProduct()">
      Add Product
    </button>
  `
})
export class Products {

  private productService = inject(ProductService);

  addProduct(): void {

    const product: CreateProduct = {
      name: 'Laptop',
      price: 75000
    };

    this.productService
      .addProduct(product)
      .subscribe({
        next: (response) => {
          console.log(response);
        },
        error: (error) => {
          console.error(error);
        }
      });
  }
}

ASP.NET Core Web API

CreateProductDto.cs

namespace ProductApi.DTOs;

public class CreateProductDto
{
    public string Name { get; set; } = string.Empty;

    public decimal Price { get; set; }
}

ProductsController.cs

using Microsoft.AspNetCore.Mvc;
using ProductApi.DTOs;

namespace ProductApi.Controllers;

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpPost]
    public IActionResult CreateProduct(
        [FromBody] CreateProductDto product)
    {
        Console.WriteLine(product.Name);
        Console.WriteLine(product.Price);

        return Ok(product);
    }
}

1. How Do You Send JSON Data from Angular to ASP.NET Core?

Suppose Angular has this TypeScript object:

const product: CreateProduct = {
  name: 'Laptop',
  price: 75000
};

We send it using:

this.http.post<CreateProduct>(
  this.apiUrl,
  product
);

The important part is:

http.post(url, body)

Here:

this.apiUrl
     ↓
Where to send


product
     ↓
Request body

Angular's HttpClient handles the normal JSON serialization of the object.

Conceptually:

TypeScript Object

{
  name: 'Laptop',
  price: 75000
}

        ↓
   HttpClient
        ↓
JSON serialization
        ↓

{
  "name": "Laptop",
  "price": 75000
}

HTTP Request

Conceptually, Angular sends:

POST /api/products
Content-Type: application/json

{
  "name": "Laptop",
  "price": 75000
}

The header:

Content-Type: application/json

tells the server:

The request body contains JSON data.

For normal object bodies, Angular HttpClient handles the JSON content type/serialization appropriately, so you generally don't need to manually call JSON.stringify().

Normally do this:

this.http.post(
  this.apiUrl,
  product
);

rather than manually doing:

this.http.post(
  this.apiUrl,
  JSON.stringify(product)
);

2. How Does ASP.NET Core Deserialize Angular JSON into a DTO?

Now consider the ASP.NET Core action:

[HttpPost]
public IActionResult CreateProduct(
    [FromBody] CreateProductDto product)
{
    return Ok(product);
}

Angular sends:

{
  "name": "Laptop",
  "price": 75000
}

ASP.NET Core sees:

[FromBody] CreateProductDto product

and creates a C# object:

CreateProductDto

Name  = "Laptop"
Price = 75000

This process involves model binding and input formatting/JSON deserialization.


What Does [FromBody] Mean?

[FromBody]

tells ASP.NET Core:

Get the value for this parameter from the HTTP request body.

For example:

[FromBody] CreateProductDto product

Request:

POST /api/products

{
  "name": "Laptop",
  "price": 75000
}

becomes:

product.Name

with:

Laptop

and:

product.Price

with:

75000

Complete Deserialization Flow

Angular
   │
   │ TypeScript Object
   ↓
{
  name: 'Laptop',
  price: 75000
}

   ↓

HttpClient.post()

   ↓

HTTP Request

   ↓

Content-Type: application/json

   ↓

{
  "name": "Laptop",
  "price": 75000
}

   ↓

ASP.NET Core

   ↓

JSON input formatter
(System.Text.Json by default)

   ↓

Model Binding

   ↓

CreateProductDto

   ↓

Name  = "Laptop"
Price = 75000

   ↓

Controller Action

How Does Property Matching Work?

Angular sends:

{
  "name": "Laptop",
  "price": 75000
}

C# has:

public class CreateProductDto
{
    public string Name { get; set; }

    public decimal Price { get; set; }
}

Notice:

JSON             C#

name       →     Name
price      →     Price

ASP.NET Core's default web JSON configuration handles this common camelCase/PascalCase difference.

Therefore:

"name"

can populate:

Name

and:

"price"

can populate:

Price

What Performs the JSON Deserialization?

ASP.NET Core uses:

System.Text.Json

by default for JSON serialization/deserialization.

Conceptually:

JSON
 ↓
System.Text.Json
 ↓
C# object

For example:

{
  "name": "Laptop",
  "price": 75000
}

becomes:

new CreateProductDto
{
    Name = "Laptop",
    Price = 75000
};

You normally do not manually write this conversion. ASP.NET Core performs it as part of request processing.


Do We Always Need [FromBody]?

With an API controller:

[ApiController]
public class ProductsController : ControllerBase

ASP.NET Core can infer that a complex type such as:

CreateProductDto

should come from the request body.

Therefore this commonly works:

[HttpPost]
public IActionResult CreateProduct(
    CreateProductDto product)
{
    return Ok(product);
}

as well as the explicit version:

[HttpPost]
public IActionResult CreateProduct(
    [FromBody] CreateProductDto product)
{
    return Ok(product);
}

For learning and interviews, the explicit version makes the source very clear:

[FromBody] CreateProductDto product

POST Example

Angular:

const product = {
  name: 'Laptop',
  price: 75000
};

return this.http.post(
  'https://localhost:7001/api/products',
  product
);

ASP.NET Core:

[HttpPost]
public IActionResult Create(
    [FromBody] CreateProductDto product)
{
    return Ok(product);
}

Flow:

Angular Object
      ↓
POST
      ↓
JSON
      ↓
Request Body
      ↓
[FromBody]
      ↓
CreateProductDto

PUT Works the Same Way

JSON request bodies are not limited to POST.

Angular:

updateProduct(
  id: number,
  product: CreateProduct
): Observable<void> {

  return this.http.put<void>(
    `${this.apiUrl}/${id}`,
    product
  );
}

ASP.NET Core:

[HttpPut("{id}")]
public IActionResult UpdateProduct(
    int id,
    [FromBody] CreateProductDto product)
{
    Console.WriteLine(id);
    Console.WriteLine(product.Name);
    Console.WriteLine(product.Price);

    return NoContent();
}

Request:

PUT /api/products/10
Content-Type: application/json

{
  "name": "Gaming Laptop",
  "price": 95000
}

ASP.NET Core receives:

id = 10

product.Name
    = "Gaming Laptop"

product.Price
    = 95000

[FromBody] vs [FromQuery] vs [FromRoute] vs [FromHeader]

This is important for ASP.NET Core interviews.

Attribute Reads From Example
[FromBody] Request body JSON DTO
[FromQuery] Query string ?page=1
[FromRoute] URL route /products/10
[FromHeader] HTTP header X-Api-Key

For example:

[HttpPut("{id}")]
public IActionResult Update(
    [FromRoute] int id,
    [FromQuery] bool notify,
    [FromHeader(Name = "X-Api-Key")] string apiKey,
    [FromBody] CreateProductDto product)
{
    return NoContent();
}

Angular might send:

PUT /api/products/10?notify=true

X-Api-Key: 123456

{
  "name": "Laptop",
  "price": 75000
}

Mapping:

URL /10
   ↓
[FromRoute]
   ↓
id = 10


?notify=true
   ↓
[FromQuery]
   ↓
notify = true


X-Api-Key: 123456
   ↓
[FromHeader]
   ↓
apiKey = "123456"


JSON Body
   ↓
[FromBody]
   ↓
CreateProductDto

DTO Validation

A DTO can also contain validation rules.

For example:

using System.ComponentModel.DataAnnotations;

public class CreateProductDto
{
    [Required]
    public string Name { get; set; } = string.Empty;

    [Range(1, 1000000)]
    public decimal Price { get; set; }
}

If Angular sends invalid data:

{
  "name": "",
  "price": -100
}

with [ApiController], ASP.NET Core can automatically return a validation error response when model validation fails.

So the broader flow becomes:

Angular JSON
     ↓
ASP.NET Core
     ↓
JSON Deserialization
     ↓
DTO
     ↓
Validation
     ↓
Controller

If validation fails:

JSON
 ↓
DTO binding/validation
 ↓
Invalid
 ↓
400 Bad Request

Request DTO vs Entity

In a real application, Angular should normally send an API contract/DTO, rather than designing the client around your EF Core entity.

For example:

Angular

CreateProduct
      ↓
JSON
      ↓
ASP.NET Core

CreateProductDto
      ↓
Application / Business Logic
      ↓
Product Entity
      ↓
EF Core
      ↓
SQL Server

This keeps the API contract separated from persistence concerns.


Important Distinction: Serialization vs Deserialization

These two terms are commonly asked in interviews.

Serialization

Object → JSON

Angular side:

TypeScript Object
       ↓
      JSON

Example:

{
  name: 'Laptop',
  price: 75000
}

becomes JSON over HTTP:

{
  "name": "Laptop",
  "price": 75000
}

Deserialization

JSON → Object

ASP.NET Core side:

JSON
 ↓
C# DTO

Example:

{
  "name": "Laptop",
  "price": 75000
}

becomes:

CreateProductDto

with:

Name  = Laptop
Price = 75000

Easy way to remember:

Serialization
Object → JSON

Deserialization
JSON → Object

Complete End-to-End Flow

ANGULAR
──────────────────────────────

CreateProduct object
{
  name: 'Laptop',
  price: 75000
}

        ↓

HttpClient.post(url, product)

        ↓

JSON Serialization

        ↓

HTTP POST
Content-Type: application/json

        ↓

{
  "name": "Laptop",
  "price": 75000
}


ASP.NET CORE
──────────────────────────────

HTTP Request

        ↓

Routing

        ↓

ProductsController

        ↓

[FromBody]

        ↓

JSON Input Formatter
System.Text.Json

        ↓

JSON Deserialization

        ↓

CreateProductDto

        ↓

Name  = "Laptop"
Price = 75000

        ↓

Controller / Application Layer

        ↓

EF Core

        ↓

SQL Server

Key Points

  • Angular HttpClient can send TypeScript objects as JSON request bodies.
  • POST syntax:
this.http.post(url, object);
  • PUT syntax:
this.http.put(url, object);
  • You normally don't need to manually call JSON.stringify() when passing an object to HttpClient.
  • JSON requests normally use:
Content-Type: application/json
  • ASP.NET Core reads JSON request bodies into DTOs using model binding and JSON input formatting.
  • [FromBody] explicitly indicates that the parameter comes from the request body.
  • System.Text.Json is the default JSON serializer in modern ASP.NET Core.
  • [ApiController] can infer body binding for complex types.
  • camelCase JSON such as name commonly maps to PascalCase C# properties such as Name.
  • DTO validation can happen after/beside binding before the controller action executes.
  • Prefer API DTOs/contracts rather than exposing EF Core entities directly.

Interview Questions and Answers

1. How do you send JSON data from Angular to ASP.NET Core?

Pass a TypeScript object as the request body to HttpClient.post() or put():

this.http.post(
  '/api/products',
  product
);

Angular HttpClient handles the normal JSON serialization.

2. How does ASP.NET Core deserialize Angular JSON into a DTO?

ASP.NET Core reads the JSON request body through its model-binding/input-formatting pipeline and uses System.Text.Json by default to deserialize it into the specified C# DTO.

public IActionResult Create(
    [FromBody] CreateProductDto product)

3. What does [FromBody] mean?

It tells ASP.NET Core to obtain the parameter value from the HTTP request body.

[FromBody] CreateProductDto product

4. Is [FromBody] mandatory with [ApiController]?

Not always. [ApiController] can infer body binding for complex types, but [FromBody] can be used explicitly for clarity.

5. Which JSON serializer does ASP.NET Core use by default?

Modern ASP.NET Core uses:

System.Text.Json

by default.

6. Do we need JSON.stringify() before calling HttpClient.post()?

Normally, no.

Pass the object directly:

this.http.post(url, product);

7. What is serialization?

Serialization converts an object into a transport representation such as JSON:

Object → JSON

8. What is deserialization?

Deserialization converts JSON into an application object:

JSON → C# DTO

9. How does Angular's name map to C# Name?

ASP.NET Core's default web JSON configuration supports the conventional JSON naming behavior and case-insensitive property matching, allowing common camelCase JSON properties to bind to PascalCase C# properties.

10. Should the Angular application send EF Core entities directly?

Typically, use API request/response DTOs as the contract:

Angular Model
      ↓
JSON
      ↓
Request DTO
      ↓
Business/Application Layer
      ↓
Domain/Entity
      ↓
Database

Short Interview Answer

Angular sends JSON by passing a TypeScript object to HttpClient.post() or HttpClient.put(). ASP.NET Core reads the JSON request body and, using its model-binding/input-formatting pipeline with System.Text.Json by default, deserializes the JSON into a C# DTO, commonly represented explicitly with [FromBody].

← Back to Articles