MVC Core Action not binding from angularjs POST - angularjs

I'm having a problem by where I am posting an object to an MVC Core controller from a simple angularjs page.
The object at my MVC action is not binding although the object itself isn't null which is the usual problem with this.
Can anyone see what I am doing wrong?
This is my angular service code:
this.getQuote = function (priceRequest) {
return $http.post('/quote/getcost', { priceRequest });
};
which is called by:
quoteService.getQuote(this.quoteData).then(function (cost) {
$scope.quoteData.quoteCost = cost.data;
});
where this.quoteData is:
$scope.quoteData = {
detailLevel: '0',
fileLengthHours: 0,
fileLengthMinutes: 1,
excessiveSpeakersCount: 1,
industry: null,
deliveryTime: '1',
additionalInformation: '',
quoteCost: null
};
This is the payload
and this is the POST:
Finally my C# MVC Core action:
[HttpPost]
public JsonResult GetCost([FromBody]PriceRequest priceRequest)
{
var price = _priceCalculator.GetPrice(priceRequest);
return new JsonResult(price);
}
Although the object posted in is not null, none of the values have been bound:
This is the PriceRequest object:
public class PriceRequest
{
public JobDetailLevel DetailLevel { get; set; }
public int FileLengthHours { get; set; }
public int FileLengthMinutes { get; set; }
public int? ExcessiveSpeakersCount { get; set; }
public JobIndustry Industry { get; set; }
public JobDeliveryTime DeliveryTime { get; set; }
public string AdditionalInformation { get; set; }
}
Can anyone see what I am doing wrong?

Ok so courtesy of this post:
Asp.net core MVC post parameter always null
I needed to add this to my startup.cs:
.AddJsonOptions(jsonOptions =>
{
jsonOptions.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
});
Thanks to those who tried to help.

Try removing the { } from around the priceRequest variable on the angular side.
Like:
return $http.post('/quote/getcost', priceRequest);

Related

.Net Core Web API not deserializing JSON from angularJS

I have this angular JS controller where I am serialising a view model to json which doesnt deserialise on the backend with a web api.
Here is my angular controller constructor..
constructor($scope, $http, $routeParams: IBookingParams) {
this.http = $http;
//get parameters from Recommendation page
this.bookingView = <IBookingViewModel>{};
this.bookingView.CampaignName = $routeParams.CampaignName;
this.bookingView.CampaignSupplierId = $routeParams.CampaignSupplierId;
this.bookingView.SupplierName = $routeParams.SupplierName;
this.bookingView.MediaChannelNames = $routeParams.MediaChannelNames;
this.bookingView.MediaChannelIds = $routeParams.MediaChannelIds;
let livedate = this.GetJSDate($routeParams.LiveDate);
let liveDateTime = this.GetDateTime(livedate);
this.bookingView.LiveDate = liveDateTime;
//populate the rest of our model
this.bookingView.Action = "from angular";
var model = this.bookingView;
let json = JSON.stringify(model);
this.http({
url: "/api/asdabooking",
method: "POST",
data: json
})
.then((response: any) => {
let test = "";
})
.catch((data: any) => {
let test = "";
});
}
Here is my web api
[HttpPost]
[Route("api/asdabooking")]
public async Task<IActionResult> BuildBookingModel([FromBody]BookingViewModel model)
{
try
{
//model is null??!!
return Ok("");
}
catch (Exception ex)
{
base.Logger.LogError(ex.Message, ex);
return BadRequest(ex.Message);
}
}
This is pretty bizarre, the bookingView view model on the front end matches the fields on the backend view model "BookingViewModel. I have inspected the json and all looks ok.
This is my view model
public class BookingViewModel
{
public string CampaignName { get; set; }
public string CampaignSupplierId { get; set; }
public string SupplierName { get; set; }
public List<string> MediaIds { get; set; }
public List<string> MediaChannelNames { get; set; }
public List<MediaChannelViewModel> MediaChannels { get; set; }
public string Action { get; set; }
public DateTime LiveDate { get; set; }
public List<int> MediaChannelIds { get; set; }
public int SupplierId { get; set; }
public bool SuccessfulSave { get; set; }
/// <summary>
/// Track which tab is updating
/// </summary>
public string TabAction { get; set; }
/// <summary>
/// Price summary - list of media channels (tabs)
/// </summary>
public List<MediaSummaryViewModel> MediaSummaries { get; set; }
public string UserMessage { get; set; }
}
This is my json
Often when I run into this issue it is caused from the types within the JSON object not matching the types of your properties that you defined within your model. I would ensure those types match. It also might help folks interested in answering this question to post a snippet of your JSON object as well as your model class.
mediaChannelIds should be
"mediaChannelIds":[
4,
5]
This is because I was getting an array from a query string using $routeParams by referring to the same parameter more than once which is a bad idea.. better to separate values with a character to get an array because you cant make it typesafe with $routeParams.. it will always give you strings.
In the JSON You can miss out fields or pass null no problem and it will still deserialise, but you can't mismatch types or the whole thing comes back as null.

Model parameter passed (HTTP POST) to Web API 2 from AngularJS is null

I am making a POST request from Angular to Web API 2:
let params = {
ReportName: reportName,
ParamName: paramName,
ParamValues: paramValues
};
this.$http.post("/reportsweb/api/reports/", params).then(response => {
deferred.resolve(response.data);
}, response => {
deferred.reject(response);
})
Web API method is defined like this:
[HttpPost]
[ResponseType(typeof(Dictionary<string, string>))]
public IHttpActionResult GetDependentParameterValues([FromBody]ArgumentModel args)
{
// args here is null for some reason
}
where ArgumentModel is defined the same way as params var in Angular:
public class ArgumentModel
{
public string ReportName { get; set; }
public string ParamName { get; set; }
public string ParamValues { get; set; }
}
However, when I hit a breakpoint in WebAPI method, I see that args = null :(
Any idea why?
Thanks.
Here is the screenshot from angular app:

How to pass two different types parameters in http POST method using angularjs to Web API?

First parameter is a complex type object(JSON) and second parameter is a simple type(String).Here I am using Web API 2.
I am putting my code below.
Web API
public class UserDetailsModel
{
[Key]
[EmailAddress]
public string LoginEmail { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Password { get; set; }
public string DisplayPic { get; set; }
[EmailAddress]
public string AlternateEmail { get; set; }
public string Organization { get; set; }
public string Occupation { get; set; }
public string Contact { get; set; }
public DateTime DoB { get; set; }
public string Gender { get; set; }
public string Country { get; set; }
public string State { get; set; }
public string City { get; set; }
public string Website { get; set; }
public string Info { get; set; }
public DateTime DateOfRegister { get; set; }
//public string LoginIP { get; set; }
public int LoginFlag { get; set; }
}
public int RegisterUser(UserDetailsModel userReg, string LoginIP)
{
.
.
.
}
angularjs
var UserDetails = {
'LoginEmail': $scope.LoginEmail,
'LoginName': $scope.LoginName,
'Password': $scope.Password,
'DoB': $scope.DoB,
'Gender': $scope.Gender,
'City': $scope.City,
'State': $scope.State,
'Country': $scope.Country
};
var request = $http({
method: 'post',
url: urlBase + '/UserDetails',
params: { 'userRegJSON': UserDetails, 'LoginIP': LoginIP }
});
Here in above code, I am getting NULL in UserDetails and 192.152.101.102 in LoginIP in Web API.
var request = $http({
method: 'post',
url: urlBase + '/UserDetails',
data: { 'userRegJSON': UserDetails, 'LoginIP': LoginIP }
});
Here in above code, I am getting NULL in both parameter UserDetails and LoginIP in Web API.
Then how to pass two or more different parameter types in http POST method using angularjs.
You cannot pass 2 types in webAPI.Either you pass everything in a single type or you can do the below
var request = $http({
method: 'post',
url: urlBase + '/UserDetails?LoginIp=' + LoginIP,
data: UserDetails,
});
In the API change the signature to
public int RegisterUser([FromBody]UserDetailsModel userReg, [FromUri]string LoginIP)
{
.
.
.
}
Go throught this:
Use simple and complex types in my api method signatures
POST multiple objects from Angular controller to Web API 2
Webapi doesn't work fairly well when you wish to pass 2 parameters in a POST
method. ModelBinding in Webapi always works against a single object because it maps a model.
There a few workarounds that you can use to make this work:
Use both POST and QueryString Parameters in Conjunction
If you have both complex and simple parameters, you can pass simple parameters on the query string. Your code should actually work with:
something like this
/baseUri/UserDetails?LoginIP=LoginIP
but that's not always possible. In this example it might not be a good idea to pass a user token on the query string though.
Refer to #Ravi A's suggestions for making changes in your code.

ASP.NET MVC: Post data from view to controller using model vs post data using angular js

Which is the best way to post data from view to controller or post data using $http service(angular js) in ASP.NET MVC?
I think you should clear your concepts from here
Here is the angular js code I think you want:
click: function ()
{
if ($scope.myform.$valid) {
var empdetails =
{
firstname: $scope.firstnamemodel,
lastname: $scope.lastnamemodel,
gender: $scope.gendermodel,
emailid: $scope.emailidmodel,
empid: Math.floor((Math.random() * 10000) + 1),
isfulltime: false,
};
//postservice.postdata(empdetails);
$http.post('/Registration/DoRegister', empdetails);
$(this).dialog("close");
$("body").css("background-color", "white");
}
And this the model class of the MVC:
public class EmpDetails
{
public string firstname { get; set; }
public string lastname { get; set; }
public string gender { get; set; }
public string emailid { get; set; }
public string empid { get; set; }
public bool isfulltime { get; set; }
}
But remember your model class variable name same as the angular js variable name
...And Here is my controller cal:
public ActionResult DoRegister(EmpDetails empdetails)
{
//some code...
}
After that bt output window print option, you can check that data is posting or not.
Hope this will help...

How to pass arrays from model to view?

I'm just learning ASP.NET MVC 3, And recently I tried a lot of times to pass arrays/lists/ICollections etc. but couldn't. everytime the list was empty.
For example, the current project:
Model:
public class Video
{
public int VideoID { get; set; }
public string Name { get; set; }
public ICollection<string> Tags { get; set; }
}
Initializer - Seed:
protected override void Seed(DatabaseContext context)
{
var videos = new List<Video>
{
new Video {
Name = "Video01",
Tags = new List<string> { "tag1", "tag2" },
};
videos.ForEach(s => context.Videos.Add(s));
context.SaveChanges();
base.Seed(context);
}
In the view: I do get the Name property, but the Tags are completely empty.
In the debug I get Tags - Count: 0.
This is not the first time it happens to me, to be honest it happens every single time when I try to pass those kind of stuff. a bit of info about the project:
ASP.NET MVC 3, Entity-Framework:Code First, SqlServerCe.4.0.
Crean an entity Tag
public class Video
{
public int VideoID { get; set; }
public string Name { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public int VideoId { get; set; }
public string TagText { get; set; }
}
or store tags to one field separated with comma /semicolon or whatever fits for your solution
By default Entity Framework doesn't load associations of an entity, you need to specify it explicitly:
var videos = context.Videos.Include("Tags");

Resources