1

I have a .Net Core 2.2 Web api that is listening to an angular front end. I send JSON data to the backend from an angular service, I check the data both in the chrome dev tools and fiddler, so I have a good idea what is being sent. The endpoint is being hit, but the body is not parsing, and my backend thinks it's null. I have looked at similar issues that people on stack overflow have had, but none of their solutions seem to work (FormBody, changing data sent, etc.). Here is my packet data from fiddler, my front end code and my webAPI/viewmodel. I put a breakpoint in my C# endpoint, and it gets hit, but the "testInstance" object is always null. Any idea why this is, maybe a character encoding?

Fiddler data

Raw:

POST https://localhost:44380/api/Shipping/shippingDoc HTTP/1.1
Host: localhost:44380
Connection: keep-alive
Content-Length: 16
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: https://localhost:44380
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36
Content-Type: application/json; charset=UTF-8
Referer: https://localhost:44380/dataentry
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

{"name":"hello"}

TextView:

{"name":"hello"}

Angular 8 frontend service:

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

  private shippingURL : string = 'api/Shipping/shippingDoc';
  constructor(private http: HttpClient) { }

  postShippingDocForm(shippingDoc : ShippingDoc) : Observable<any> {
    var headers = new HttpHeaders().set('Content-Type', 'application/json; charset=utf-8');
    var test = {name: "hello"} //dummy data
    return this.http.post(this.shippingURL, test, {headers: headers});
  }
}

.Net core web api:

namespace TrackingSystem.Controllers
    {
        [Route("api/Shipping")]
        public class ShippingController : ControllerBase
        {

            [HttpPost("shippingDoc")]
            [ProducesResponseType(StatusCodes.Status201Created)]
            [ProducesResponseType(StatusCodes.Status400BadRequest)]
            public ActionResult<Views.Shipping.Test> CreateShippingDocForm(Views.Shipping.Test testInstance) 
            {
                return testInstance; //breakpoint is here
            }

        }
    }

.Net core view model:

namespace TrackingSystem.Views.Shipping
{
    public class Test
    {
        public string name { get; set; }
    }
}
Goku
  • 1,565
  • 1
  • 29
  • 62

1 Answers1

1

In order to bind the JSON correctly in ASP.NET Core, you must modify your action to include the attribute [FromBody] on the parameter. This tells the framework to use the content-type header of the request to decide which of the configured IInputFormatters to use for model binding.

public ActionResult<Views.Shipping.Test> CreateShippingDocForm([FromBody] Views.Shipping.Test testInstance) 
{
    return testInstance; //breakpoint is here
}
penleychan
  • 5,370
  • 1
  • 17
  • 28
  • could you point me to documentation on this? – Goku Jul 29 '19 at 15:27
  • @Goku https://learn.microsoft.com/en-us/aspnet/core/web-api/?view=aspnetcore-2.2#binding-source-parameter-inference – penleychan Jul 29 '19 at 15:31
  • why in this example, do they chose not to use "[FromBody]" in the post request https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-2.2&tabs=visual-studio – Goku Jul 29 '19 at 15:37
  • 1
    Simple, your code doesn't handle JSON type binding to complex type because you don't have `[ApiController]` attribute. Thus you need that `[FromBody]` – penleychan Jul 29 '19 at 16:13