Angular Service:-
app.service('loginService', ['$http', function ($http) {
this.userLogin = function (user) {
console.log(user); //prints {'username': 'username#gmail.com', 'password': 123'}
$http(
{
url: "/api/user/login",
method: "POST",
data: { 'model': user },
contentType: "application/json"
})
.then(function (data) {
if (data.status.toLower() === "success") {
return data;
}
else {
return null;
}
});
}
Angular Controller
app.controller('homeCtrl', ['$scope', 'loginService', function ($scope, loginService) {
$scope.login = function (user) {
debugger;
console.log($scope.user);
var data = loginService.userLogin($scope.user);
}
}]);
WebAPI.
[Route("api/user/login")]
public void Post([FromBody]LoginVM model)
{
if(ModelState.IsValid)
{
}
else
{
}
}
But when I debug the WebAPI model it has all the values as null.
My LoginVM class
[Required]
public string Username { get; set; }
[Required]
public string Password { get; set; }
Why I am getting the properties as null?
Your passing your content type header incorrectly. It get's passed as part of the headers parameter like so:
$http({
url: "/api/user/login",
method: "POST",
data: { 'model': user },
headers: {
"Content-Type": "application/json"
}
}).then(function (data) {
if (data.status.toLower() === "success") {
return data;
} else {
return null;
}
});
However, unless you have changed the default headers you don't even need to pass the content type. See the default headers in the documentation.
So you can simply make your request like so:
$http({
url: "/api/user/login",
method: "POST",
data: {
model: user
}
}).then(function (data) {
if (data.status.toLower() === "success") {
return data;
} else {
return null;
}
});
And you shouldn't need the [FromBody] Attribute on your method because your LoginVM is a complex type (Class).
Also, I've had it in the past where sometimes visual studio plays up and it's not debugging correctly. It's worth closing visual studio and re-opening it if that's the IDE you're using.
Related
I tried everything yet still when debugging the value at the web api post action is always null.
i tried changing the headers, i added [JsonObject(MemberSerialization.OptOut)] above the posted model class, i tried a simple Dto. nothing works...
this is the controller function that passes the user data:
$scope.Add = function () {
var user = {
ID: $scope.ID,
FirstName: $scope.FirstName,
LastName: $scope.LastName,
Age: $scope.Age,
Address: $scope.Address
};
$scope.usersRepo.push(user);
myService.addUser(user);
the service function is:
var addUser = function (user) {
return $http.post(
usersApi + '/addNewUser',
JSON.stringify(user)),
{
headers: {
'Content-Type': 'application/json'
}
};
};
and the web api action is:
[HttpPost, ActionName("addUser")]
public void Post([FromBody]UserModel value)
{
UsersDB.Add(value);
}
my model is this:
[JsonObject(MemberSerialization.OptOut)]
public class UserModel
{
public UserModel()
{
}
public UserModel(string firstName, string lastName, int age, string address)
{
this.Address = address;
this.Age = age;
this.FirstName = firstName;
this.LastName = lastName;
}
public void ConvertDto(UserDto userDto)
{
ID = userDto.ID;
FirstName = userDto.FirstName;
LastName = userDto.LastName;
Age = userDto.Age;
Address = userDto.Address;
}
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public string Address { get; set; }
}
Use http post method like this. data should be your object to be passed without json stringify. I advised you to create a service for http methods.
var obj = {
url: your url,
async: true,
method: 'POST',
headers: {
"content-type": "application/json; charset=utf-8",
}
};
if (typeof data != 'undefined' && typeof data != null) {
obj.data = data;
}
$http(obj).then(function() {}, function() {});
Service :
// http methods
app.service('MethodProvider', ['$http', function ($http) {
var self = this;
self.get = function (url, data) {
var obj = {
url: url,
async: true,
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
};
if (typeof data != 'undefined' && data != null) {
obj.params = data;
}
return $http(obj);
};
self.post = function (url, data) {
var obj = {
url: url,
async: true,
method: 'POST',
headers: {
"content-type": "application/json; charset=utf-8",
}
};
if (typeof data != 'undefined' && typeof data != null) {
obj.data = data;
}
return $http(obj);
};
self.put = function (url, data) {
var obj = {
url: url,
async: true,
method: 'PUT',
headers: {
'Content-Type': 'application/json'
}
};
if (typeof data != 'undefined' && data != null) {
obj.data = JSON.stringify(data);
}
return $http(obj);
};
self.delete = function (url) {
var obj = {
url: url,
async: true,
method: 'DELETE',
headers: {
'Content-Type': 'application/json'
}
};
if (typeof data != 'undefined' && data != null) {
obj.data = JSON.stringify(data);
}
return $http(obj);
};
}]);
I am trying to call the method ProcessCriteria in AngularJS below but for some reason I am keep getting error message:
VM18010:1 POST http://example.com/api/TalentPool/ProcessCriteria 404
(Not Found)
Below is my Calling code:
var param = { 'Item': item.Key, 'SolrLabel': SolrLabel };
$http({
method: 'POST',
url: '/api/TalentPool/ProcessCriteria',
data: param
//headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
//}
}).then(function (response) {
// success
console.log('Facet Data Posted');
return response;
},
function (response) { // optional
// failed
console.log('facet post error occured!');
});
And my Server side method:
[System.Web.Http.HttpPost]
public IHttpActionResult ProcessCriteria(string Item, string SolrLabel)
{
var itm = Item;
var solr = SolrLabel;
return Ok();
}
Any suggestions please?
ASP.net cannot match your request in its Route Table because you have 2 parameters in your action and the router doesn't understand it.
it expects a data object that your parameters warp to this.
First of all, make a Model like it:
public class Criteria
{
public string Item { get; set; }
public string SolrLabel { get; set; }
}
then change your action:
[System.Web.Http.HttpPost]
public IHttpActionResult ProcessCriteria(Criteria criteria)
{
var itm = criteria.Item;
var solr = criteria.SolrLabel;
return Ok();
}
Update
and update your javaScript part with JSON.stringify:
var param = { 'Item': item.Key, 'SolrLabel': SolrLabel };
$http({
method: 'POST',
url: '/api/TalentPool/ProcessCriteria',
data: JSON.stringify(param)
//headers: {
// 'Content-Type': 'application/x-www-form-urlencoded'
//}
}).then(function (response) {
// success
console.log('Facet Data Posted');
return response;
},
function (response) { // optional
// failed
console.log('facet post error occured!');
});
You can create a class as said by in above answer and you can pass data in http post like this
var obj = {
url: url,
async: true,
method: 'POST',
headers: {
"content-type": "application/json; charset=utf-8",
}
};
if (typeof data != 'undefined' || typeof data != null) {
obj.data = data;
}
$http(obj).then(function(response){
},function(error){
});
I got i working, below is the code for others if they get stuck on it.
var pvarrData = new Array();
pvarrData[0] = JSON.stringify(item.Key);
pvarrData[1] = JSON.stringify(SolrLabel);
pvarrData[2] = JSON.stringify($localStorage.message);
$http({
method: 'POST',
url: '/api/TalentPool/ProcessCriteria',
data: JSON.stringify(pvarrData),
headers: { 'Content-Type': 'application/json' }
}).then(function (response) {
// success
console.log('Facet Data Posted');
return response;
},
function (response) {
// failed
console.log('facet post error occured!');
});
In my controller i have the following
[HttpPost]
public string AddEmployee(Employee Emp)
{
if (Emp != null)
{
_context.Employees.Add(Emp);
_context.SaveChanges();
return "Employee Updated";
}
else
{
return "Invalid Employee";
}
}
When i use the following in my angularjs factory no data is passed.
EmployeeService.AddEmp = function (employee) {
console.log(employee);
var response = $http({
method: "post",
url: "/Home/AddEmployee",
data: JSON.stringify(employee),
dataType: "json"
});
return response;
}
but when i use the following data is passed. What am i doing wrong with the above code.
EmployeeService.AddEmp = function (employee) {
console.log(employee);
var response = $http({
method: "post",
url: "/Home/AddEmployee",
params: {
employeeCode: JSON.stringify(employee.employeeCode),
firstName: JSON.stringify(employee.firstName),
lastName: JSON.stringify(employee.lastName),
}
});
return response;
}
I think you'll need to add something like this:
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
to WebApiConfig.Register
I'm creating a js object with the same properties as my controller action expects as parameters.
controller.js
(function () {
'use strict';
angular
.module('app')
.controller('requestController', requestController);
requestController.$inject = ['$scope', 'lecturesFactory', 'attendeesFactory'];
$scope.setSelectedLectures = function () {
var lecture1, lecture2;
for (var i = $scope.lectures.length - 1; i >= 0; i--) {
var lecture = $scope.lectures[i];
if (lecture.selected === true) {
if (lecture1 == null) {
lecture1 = lecture.lectureId;
}
else {
lecture2 = lecture.lectureId;
}
}
}
attendeesFactory.setSelectedLectures($scope.emailAddress.text, lecture1, lecture2).then(function (data) {
$scope.showInvalidUserMessage = true;
$scope.message = data.message;
});
};
activate();
function activate() { }
}
})();
attendessFactory.js
(function () {
'use strict';
angular
.module('app')
.factory('attendeesFactory', attendeesFactory);
attendeesFactory.$inject = ['$http'];
function attendeesFactory($http) {
var service = {
setSelectedLectures: setSelectedLectures
};
return service;
function setSelectedLectures(emailAddress, lecture1, lecture2) {
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: {
emailAddress: emailAddress,
lecture1: lecture1,
lecture2: lecture2
}
}).then(function (response) {
console.log(response);
return response.data;
});
return promise;
}
}
})();
And my MVC Controller:
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
[HttpPost]
public IActionResult SetSelectedLectures(SelectedLectureData data)
{
// ...
}
}
public class SelectedLectureData
{
public String EmailAddress { get; set; }
public int Lecture1 { get; set; }
public int? Lecture2 { get; set; }
}
I've tried what some posts on StackOverflow suggested, such as using JSON.stringify, changing the content-type, but I still get the parameter values null (even if I put them directly in the action, instead of using a custom class).
Use [FromBody] anotation to make it working which will serialize data in SelectedLectureData model.
public IActionResult SetSelectedLectures([FromBody]SelectedLectureData data)
Otherwise you need to do
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: JSON.strigify({ "data": {
emailAddress: emailAddress,
lecture1: lecture1,
lecture2: lecture2
}})
})
Try updating your javascript to
function setSelectedLectures(emailAddress, lecture1, lecture2) {
var model = {
emailAddress: emailAddress,
lecture1: lecture1,
lecture2: lecture2
};
var data = JSON.strigify(model);
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: data
}).then(function (response) {
console.log(response);
return response.data;
});
return promise;
}
and using [FromBody] attribute on controller action
[HttpPost]
public IActionResult SetSelectedLectures([FromBody]SelectedLectureData data)
{
// ...
}
JSON property name should be same as class properties else it will take it as null
function setSelectedLectures(emailAddress, lecture1, lecture2) {
var promise = $http({
method: 'POST',
url: '/Home/SetSelectedLectures',
data: {
EmailAddress : emailAddress,
Lecture1: lecture1,
Lecture2: lecture2
}
}).then(function (response) {
console.log(response);
return response.data;
});
I am trying to make an update to an existing object but get the following error $scope.entry.update is not a function.
I created a service called 'budgetResource'
"use strict";
angular.module("common.services").factory("budgetResource", ["$resource", "appSettings", budgetResource])
function budgetResource($resource, appSettings) {
return $resource(appSettings.serverPath + "api/budget/:id", null,
{
'update': { method: 'PUT', isArray: true },
'delete': { method: 'DELETE', isArray: true },
'save': { method: 'POST', isArray: true }
});
}
Herewith the function in my controller where budgetResource service is injected with the function $scope.updateBudgetAmount being called.
$scope.updateBudgetAmount = function (categoryId) {
$scope.entry = new budgetResource();
$scope.entry = {
"budgetAmount": $scope.budgetAmount,
"categoryId": categoryId
}
$scope.entry.update({ id: categoryId },
function (data) {
$scope.categories = data;
$scope.category = "";
},
function (error) {
$scope.message = error.statusText;
});
}
which in turn calls the webapi method
public IHttpActionResult Put(int id, [FromBody]Category cat)
{
try
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
BudgetRepository repo = new BudgetRepository();
var categories = repo.SaveCategory(cat);
return Ok(categories);
}
How can modify this so that it is dine correctly?
After you do $scope.entry = {...},$scope.entry becomes a plain javascript object, so $scope.entry.update is not exist.