Reputation: 95
I've looked on a number of posts already, but I can't see what I've been doing wrong. I suspect that there is a small issue that I've become blind to. I'm hoping someone can point me in the right direction.
I have an API controller which takes HTTPPost, I have a view which is using an AngularJS controller.
The problem I am having is that I can see the request being posted using Fiddler. However the API controller which takes a parameter of Invoice seems to be receiving null. I've checked other posts on here, and although I've found similar issues I haven't been able to find what is wrong in the implementation I have.
Any Ideas? Code below...
The Models are as below;
[Serializable]
public class Invoice
{
[JsonProperty(PropertyName = "invoiceId")]
public Guid InvoiceId { get; set; }
[JsonProperty(PropertyName = "customer")]
public Customer Customer { get; set; }
[JsonProperty(PropertyName = "productDetails")]
public Product ProductDetails { get; set; }
}
[Serializable]
public class Product
{
[JsonProperty(PropertyName = "product")]
public string ProductName { get; set; }
}
[Serializable]
public class Customer
{
[JsonProperty(PropertyName = "customerID")]
public Guid CustomerId { get; set; }
[JsonProperty(PropertyName = "firstName")]
public string Firstname { get; set; }
[JsonProperty(PropertyName = "lastName")]
public string Lastname { get; set; }
[JsonProperty(PropertyName = "address1")]
public string Address1 { get; set; }
[JsonProperty(PropertyName = "address2")]
public string Address2 { get; set; }
[JsonProperty(PropertyName = "town")]
public string Town { get; set; }
[JsonProperty(PropertyName = "county")]
public string County { get; set; }
[JsonProperty(PropertyName = "postCode")]
public string PostCode { get; set; }
}
The AngularJS controller is as below;
// define angular module/app
var formApp = angular.module('invoice', [])
.controller('invoiceCtrl', function ($scope, $http) {
$scope.invoiceDetails = {
invoiceId: "fbd7fe22-81b1-4886-8d0e-13be442b8444",
customer: {
firstName: "Joe",
lastName: "Bloggs",
address1: "1 Somewhere",
address2: "",
town: "Oxford",
county: "OXON",
postCode: "OX26 5TY"
},
productDetails: {
product:"prod name"
}
}
// process the form
$scope.processForm = function () {
$http.post(
'/api/invoice',
JSON.stringify($scope.invoiceDetails),
{
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
}
)
.success(function (data) {
console.log(data);
if (!data.success) {
// if not successful, bind errors to error variables
$scope.errorFirstName = data.errors.firstname;
$scope.errorLastName = data.errors.lastName;
} else {
// if successful, bind success message to message
$scope.message = data.message;
}
});
};
});
And the view which posts the details is as below;
<div ng-app="invoice" ng-controller="invoiceCtrl">
<h2 class="content-margin">Create Invoices using this page</h2>
<h5 class="content-margin">Invoice ID </h5><span ng-model="invoiceDetails.invoiceId"></span>
<form class="form-horizontal" ng-submit="processForm()">
<h4>Customer Details</h4>
<div class="form-group">
<label for="Forename" class="control-label col-xs-2">Customer Forename:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="Forename" placeholder="" ng-model="invoiceDetails.customer.firstName">
</div>
</div>
<div class="form-group">
<label for="Surname" class="control-label col-xs-2">Customer Surname:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="Surname" placeholder="" ng-model="invoiceDetails.customer.lastName">
</div>
</div>
<div class="form-group">
<label for="AddressLine1" class="control-label col-xs-2">Address Line 1:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="AddressLine1" placeholder="" ng-model="invoiceDetails.customer.address1">
</div>
</div>
<div class="form-group">
<label for="AddressLine2" class="control-label col-xs-2">Address Line 2:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="AddressLine2" placeholder="" ng-model="invoiceDetails.customer.address2">
</div>
</div>
<div class="form-group">
<label for="City" class="control-label col-xs-2">City:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="City" placeholder="" ng-model="invoiceDetails.customer.town">
</div>
</div>
<div class="form-group">
<label for="County" class="control-label col-xs-2">County:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="County" placeholder="" ng-model="invoiceDetails.customer.county">
</div>
</div>
<div class="form-group">
<label for="PostCode" class="control-label col-xs-2">Post Code:</label>
<div class="col-xs-10 col-md-6 col-lg-5">
<input type="text" class="form-control" id="PostCode" placeholder="" ng-model="invoiceDetails.customer.postCode">
</div>
</div>
<input type="submit" name="Submit" value="Submit" class="btn btn-success btn-large" />
</form>
</div>
EDIT
The controller action being called is as below;
[HttpPost]
public async Task<HttpResponseMessage> Post([FromBody]Invoice invoiceDetails)
{
if (invoiceDetails == null) return this.Request.CreateResponse(HttpStatusCode.BadRequest);
// _invoiceRepository.Add(value);
return this.Request.CreateResponse(HttpStatusCode.OK, new { });
}
The post is as per below
{
"invoiceId": "fbd7fe22-81b1-4886-8d0e-13be442b8444",
"customer": {
"firstName": "Joe",
"lastName": "Bloggs",
"address1": "1 Somewhere",
"address2": "",
"town": "Oxford",
"county": "OXON",
"postCode": "OX26 5TY"
},
"product": {
"productName": "Prod reg"
}
}
Upvotes: 0
Views: 232
Reputation: 2786
The main problem is Serializable
attribute on your models. If you remove them everything will work fine. If you need this attribute for some other stuff and can't remove, then you can add JsonObject
attribute:
[JsonObject]
[Serializable]
public class Invoice
{
// Properties
}
Don't forget to do it for all classes that are deserialized from JSON.
Also in last JSON sample that you posted you have carDetails
instead of productDetails
. I think it's just a typo.
Upvotes: 1