I trying to post to a api with accepts an integer parameter using angular as below
function getDailyErrors() {
var uri = "/api/users/error-counts/";
var inData = { numberOfDays : 5}
return $http.post(uri, inData)
.then(function (response) {
return response.data;
});
}
API
[HttpPost]
[Route("api/users/error-counts/")]
public MultiCategorySeriesDto<int> GetErrorCounts(int numberOfDays=15)
{
return _uow.Events.Errors(numberOfDays);
}
for some reasons the API doesn't accept the parameter I passed instead takes the default int parameter.
May I know where the mistake is?
Try using a view model:
public class MyViewModel
{
public int NumberOfDays { get; set; }
}
that your controller action will take as parameter:
[HttpPost]
[Route("api/users/error-counts/")]
public MultiCategorySeriesDto<int> GetErrorCounts(MyViewModel model)
{
return _uow.Events.Errors(model.NumberOfDays);
}
As this is a POST, try using the [FromBody] attribute on the parameter to let the model binder know where to look for the data
[HttpPost]
[Route("api/users/error-counts/")]
public MultiCategorySeriesDto<int> GetErrorCounts([FromBody]int numberOfDays = 15)
{
return _uow.Events.Errors(numberOfDays);
}
The below code works fine for me, using the same API code as posted in your question.
global.Himanshu.ErrorServices.factory('errorcountservices', ['$q', '$http', function ($q, $http) {
return {getDailyErrors: fucntion() {
var deffered = $q.defer();
$http({
method: 'POST',
url:/api/users/error-counts/',
params: {
numberOfDays: 5
},
}).then(function (response) {
deffered.resolve(response.data);
},function (response) {
deffered.reject(response.data);
})
return deffered.promise;
}}
Related
I need to pass data entered in AngularJS front end to webAPI and retrieve another set of data to populate on a grid. I am trying to pass data as JSON object to webAPI method. In WebAPI method, the parameter I am passing for the JSON object as a Class object.
I am not able to enter to the particular webAPI method when I am using [HTTPPost], but I am able to enter to the webAPI method when I am using [HTTPGet]. But in that case the class object which is the parameter in the webAPI method shows NULL value.
Can you please advise how to fix the issue.
WebAPI
namespace webAPITestProject.Controllers
{
[Route("NewRoute")]
public class ValuesController : ApiController
{
retrieveEmployeeData empData = new retrieveEmployeeData();
retrieveProductDetails prodDetls = new retrieveProductDetails();
[Route("http://localhost:212122/api/Values/GetEmployeeData?EmployerDetls=")]
[HttpPost]
public DataTable getEmployeeData(HttpRequestMessage request,[FromBody] Employer empDetails)
{
DataTable dataTable = new DataTable { TableName = "MyTableName" };
dataTable = empData.getEmployeeData(empDetails);
return dataTable;
}
}
}
AngularJS-Controller
angular.module('Test.Employer')
.controller('EmployerController', ['$scope','headerValue', '$http',
function ($scope, headerValue, $http) {
var ipEmployerDetls = {
EmployerName: "cherokee",
Company: "ABC"
};
$http({
url: "http://localhost:212122/api/Values/GetEmployeeData?EmployerDetls=",
dataType: 'json',
method: 'POST',
data: JSON.stringify(ipEmployerDetls),
headers: {
"Content-Type": "application/json"
}
}).success(function (response) {
$scope.object = response.data;
})
.error(function (error) {
alert(error.Message);
});
})();
Employer class
public class Employer
{
string _companyCode = "";
string _employerName = "";
public string Company
{
get
{
return _companyCode;
}
set
{
_companyCode = value;
}
}
public string EmployerName
{
get
{
return _employerName;
}
set
{
_employerName = value;
}
}
}
First of, the Route
Don't include querystrings in the route to the endpoint, the querystrings are by default bound to the parameters in the method signature if you pass them.
Define the controller route with the RoutePrefix attribute and the method route with the Route attribute. The both will be combine at runtime to create the method
route, in this case api/Values/GetEmployeeData.
Then, the Method parameters
You don't need define the HttpRequestMessage as an parameter. You can get that through the HttpContext from within the method by just writing HttpContext.Current.
Finally, you are declaring the dataTable and then reasign it the line after. You should simple do the last.
So, try it like this
[RoutePrefix("api/Values")]
public class ValuesController : ApiController
{
retrieveEmployeeData empData = new retrieveEmployeeData();
retrieveProductDetails prodDetls = new retrieveProductDetails();
[Route("GetEmployeeData")]
[HttpPost]
public DataTable getEmployeeData([FromBody] Employer empDetails)
{
var dataTable = empData.getEmployeeData(empDetails);
return dataTable;
}
}
NOTE: The name getEmployeeData looks more suited to be a GET request then a POST.
Also, make the get and set in the Employer class the newer, simpler syntax
public class Employer
{
public string Company { get; set; }
public string EmployerName { get; set; }
}
UPDATE
Your client should be
angular.module('Test.Employer')
.controller('EmployerController', ['$scope','headerValue', '$http',
function ($scope, headerValue, $http) {
var ipEmployerDetls = {
EmployerName: "cherokee",
Company: "ABC"
};
$http({
url: "http://localhost:212122/api/Values/GetEmployeeData",
method: 'POST',
data: JSON.stringify(ipEmployerDetls),
headers: {
"Content-Type": "application/json"
}
}).success(function (response) {
$scope.object = response.data;
})
.error(function (error) {
alert(error.Message);
});
})();
I need to call Initailly the parameterized constructor from the angular js $http url that which maps the action method in MVC .
My angular js controller code is as follows:-
var app = angular.module("ourSiteLogIn", []);
app.controller("ourSiteLogInController", function ($scope, $http) {
$scope.GetLogInByUserIdPassword = function () {
$http({
method: "POST",
url: "User/GetLogInByUserIdPassword",
params: {
UserId: $scope.UserId,
Password: $scope.Password
}
}).then(function mySuccess(response) {
$scope.User = response.data;
}, function myError(reason) {
$scope.error = reason.data;
});
};
});
below is my controller :
public class UserController : Controller
{
private readonly ILogIn _login;
private readonly IExceptionLog _exceptionlog;
public UserController()
{
}
public UserController(ILogIn login, IExceptionLog exceptionLog)
{
_login = login;
_exceptionlog = exceptionLog;
}
[HttpPost]
public JsonResult GetLogInByUserIdPassword(string UserId, string Password)
{
try
{
Encrypt objEncrypt = new Encrypt();
tblLogIn objtblLogIn = new tblLogIn();
objtblLogIn = _login.GetLogInByUserIdPassword(UserId, objEncrypt.EncryptText(Password));
return Json(objtblLogIn, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
_exceptionlog.insertExceptionLog(ex);
return null;
}
}
}
here the problem is i am getting _login as null value while calling this method "GetLogInByUserIdPassword" and this method is presnt in another project. And by default it is calling default constructor but not calling the parameterized constructor. Any ideas will be appreciated.Thanks.
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;
});
Below is my angular and Web APi Code.In the post method null is getting passed instead of India
Angular Code:
HWApp.controller('TestCtrl', function ($scope, $http) {
$scope.SendData = function (Data)
{
$scope.whoo = Data;
console.log(Data);
$http({
url: "api/call/firstCall",
dataType: 'json',
method: 'POST',
data: "India",
headers: {
"Content-Type": "application/json"
}
}).success(function (response) {
$scope.whoo = response;
})
.error(function (error) {
alert(error);
});
}
}
);
Web Api Controller
public class CallController : ApiController
{
[HttpGet]
public string firstCallGet( )
{
return "Get";
}
[HttpPost]
public string firstCall([FromBody] string a)
{
return a;
}
}
Your data parameter should be JSON object.
data :{country : "India" }
Define a model class to automatically deserialze into.
Public class CountryViewModel{
Public string Country{get; set;}
}
Web Api controller should be as follows
public class CallController : ApiController
{
[HttpPost]
public string FirstCall( CountryViewModel in)
{
return in.Country;
}
}
This is the delete Button:
<td><input type="button" value="delete" ng-click="deleteUser(u.id)"></td>
Here is the JS file:
var app = angular.module('MyApp', ['ngResource']);
app.factory('baseRequest', ["$resource", function ($resource) {
return $resource("/apis/:method/:id", {method:'#method',id: '#id'}, {
query: {method: 'get', isArray: false}
});
}]);
app.controller("MyCtrl", ["$scope", "baseRequest", function ($scope, baseRequest) {
$scope.users = [];
$scope.fetchAllUsers = function () {
$scope.users = baseRequest.query({method: "getPageData.req"});
console.log($scope.users);
};
$scope.fetchAllUsers();
/**
* here is the delete method
*
**/
$scope.deleteUser = function (id) {
baseRequest.delete({method: "deleteUser.req", id: id}, function (response) {
console.log(response);
}, function (error) {
console.log(error);
});
};
}]);
Now when I click the delete Button, it shows error like: 403,Access to the specified resource has been forbidden.
request info:
Request URL:http://localhost:8080/apis/deleteUser.req/2
Request Method:DELETE
Status Code:403
Remote Address:[[::1]]:8080
Here is the SpringMVC controller:
#RequestMapping("/apis")
#Controller
public class UserController {
#Autowired
private UserDao userDao;
#ResponseBody
#RequestMapping(value = "/getPageData", method = RequestMethod.GET)
public Page<User> getDatas(#RequestParam(value = "pageNo", required = false, defaultValue = "1") String No) {
int pageNo = Integer.parseInt(No);
if (pageNo < 0) {
pageNo = 1;
}
return userDao.getPageData(pageNo);
}
#ResponseBody
#RequestMapping(value = "/deleteUser/{id}", method = RequestMethod.DELETE)
public String deleteUser(#PathVariable("id") Integer id) {
System.out.println(id);
if (userDao.deleteUser(id)) {
return "1";
} else {
return "0";
}
}
}
Looks like it is a server side mapping issue but you can try passing a different parameters to the delete action of $resource. Try changing it from:
baseRequest.delete({method: "deleteUser.req", id: id}, function (response) {})
to
baseRequest.delete({method: "deleteUser.req", id: id}, {}, function (response) {
I think I have found an answer to solve this issue. The key is that while you transmit a parameter with a suffix URL(like /XX.req), then it will happen this error: the server side can't recognize this request.
For example:
wrong: localhost:8080/apis/deleteUser.req/2
right: localhost:8080/apis/deleteUser/2
Maybe I should try this:(I haven't tested it)
http://localhost:8080/apis/2/deleteUser.req
=======================================================
After I tested the ideas above, both of them worked well. Of course, we should user the last one.
localhost:8080/apis/2/deleteUser.req
so, I just exchange the position of the URL parameters like this:
$resource("/apis/:id/:method/", {method:'#method',id: '#id'}