I Am trying to call an Async method in MVC controller (example Login) from an angular client and calls fail. I tried it with google postman tool also.
//
// POST: /Account/Login
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
if (!ModelState.IsValid)
{
return View(model);
}
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, change to shouldLockout: true
var result = await SignInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, shouldLockout: false);
switch (result)
{
case SignInStatus.Success:
return RedirectToLocal(returnUrl);
case SignInStatus.LockedOut:
return View("Lockout");
case SignInStatus.RequiresVerification:
return RedirectToAction("SendCode", new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
case SignInStatus.Failure:
default:
ModelState.AddModelError("", "Invalid login attempt.");
return View(model);
}
}
and here is the snippet of the angular service that is calling the Login method
var loginUser = function (email, password, returnUrl) {
var req = {
method: 'post',
url: '/Mysite/Login',
headers: {
'Content-Yype': undefined
},
data: {
model: {
Email: email,
Password: password,
RememberMe: false
},
returnUrl: returnUrl
}
};
return $http(req)
.then(function (response) {
return response.data;
}, function (reason) {
return reason;
});
};
the response throws me internal error with status 500.
Does angular.js support asynchronous calls to web methods?
Thanks and appreciate your help
If you are using the [ValidateAntiForgeryToken] decorator, the action needs a request verification token to be passed in the post data.
You could remove [ValidateAntiForgeryToken] but this would leave your action open to tampered requests.
The other option is to add an anti forgery token to the page and then pass its value in the request.
Your razor view will need a form with a token in it (Note: This is just a dummy form to allow the token to be added to the page).
#using(Html.BeginForm("Login", "ControllerName", FormMethod.Post, new { id = "verification-form"}) {
#Html.AntiForgeryToken()
}
In your javascript, you can then pass its value
var loginUser = function (email, password, returnUrl) {
var req = {
method: 'post',
url: '/Mysite/Login',
headers: {
'Content-Type': undefined
},
data: {
model: {
Email: email,
Password: password,
RememberMe: false
},
__RequestVerificationToken: $("#verification-form input[name=__RequestVerificationToken]").val(),
returnUrl: returnUrl
}
};
return $http(req)
.then(function (response) {
return response.data;
}, function (reason) {
return reason;
});
};
Related
I have a little problem with routing in my app Angular + wep api. I want to put user, and it doesn't work. Server returns 404 and error:
Failed to load resource: the server responded with a status of 404 (Not Found)
and
Message":"No HTTP resource was found that matches the request URI 'http://localhost:53544/api/Users/PutUser/1'.","MessageDetail":"No action was found on the controller 'Users' that matches the name 'PutUser'."
It's strange because the method exists.
The entirety of my code follows:
My route:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
My put method:
[HttpPut]
[ActionName("PutUser/{userId}")]
[ResponseType(typeof(void))]
public IHttpActionResult PutUser(int userId, User user)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (userId != user.Id)
{
return BadRequest();
}
db.Entry(user).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!UserExists(userId))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
My angular put method:
this.PutUser = function (userId, user) {
var promise = $http({
method: 'PUT',
url: 'api/Users/PutUser/' + userId,
data: user
})
.then(function (response) {
return "update";
},
function (response) {
return response.statusText;
});
return promise;
}
Specify the [FromUri] and [FromBody] to define parameter mapping
[HttpPut]
[ActionName("PutUser/{userId}")]
[ResponseType(typeof(void))]
public IHttpActionResult PutUser([FromUri]int userId, [FromBody]User user)
{
You have to make sure that the post request HTTP header contains
Content-Type: application/x-www-form-urlencoded
I'm trying to use Angularjs to send a Post request to My Spring Mvc Controller to login User.But I can't get the Parameter from the request.
this is my Angular js code:
$scope.submit = function () {
$http({
url: serviceURL.LoginUrl,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: {
phone: $scope.userName,
password: $scope.userPsw,
}
}).success(function (data) {
if (!data.state) {
alert(data.errorMsg);
} else {
alert('success');
}
console.log(data);
}).error(function (data) {
console.log('服务器错误!');
});
}
and this is the Spring MVC Controller code:
#RequestMapping(value = "/login", method = RequestMethod.POST)
#ResponseBody
public Object loginUser(Model model,User user, HttpSession session, HttpServletRequest request) {
String phone = request.getParameter("phone");
String password = request.getParameter("password");
System.out.println(phone+","+password);
System.out.println(user.getPhone()+","+user.getPassword());
UserDTO u = userService.loginUser(phone, password);
session.setAttribute("loginUser",u.getUser());
return u;
}
I have searched many resource,they said I should change the header and I have set the header:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET,POST,OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
return true;
}
Actually,I can't request the login url,but after I setHeader,I can request the url,but the parameter is null.
Forgive my poor English, I am newbie in StackOverFlow.
I didn't konw is it have the same question in here ,but I can find the same question. Thank you for your view.
There are two points to fix. At first, data should be converted to a URL-encoded string. You can convert data object with $.param() method or set params property instad of data so it will look like this:
$scope.submit = function () {
$http({
url: serviceURL.LoginUrl,
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
params: {
phone: $scope.userName,
password: $scope.userPsw,
}
}).success(function (data) {
if (!data.state) {
alert(data.errorMsg);
} else {
alert('success');
}
console.log(data);
}).error(function (data) {
console.log('服务器错误!');
});
}
The second point is server-side controller method. Here you have to annotate method's arguments appropriately. Consider using #RequestParam annotation.
#RequestMapping(value = "/login", method = RequestMethod.POST)
#ResponseBody
public Object loginUser(
#RequestParam String phone,
#RequestParam String password,
HttpSession session,
HttpServletRequest request
) {
System.out.println(phone + ", " + password);
UserDTO u = userService.loginUser(phone, password);
session.setAttribute("loginUser", u.getUser());
return u;
}
<!--In your script-->
var app = angular.module("myApp", [])
.controller("myController", function($http){
var vm= this;
Posting = function(name)
{
var data = 'name=' + name;
var url="example.htm";
$http.post(url, data).then(function (response) {
vm.msg = response.data;
alert(vm.msg);
});
}
});
// Above is same as using GET, but here below is important
//Dont forget to add this config ortherwise http bad request 400 error
app.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded; charset=UTF-8';
}]);
//In spring controller same as of GET Method
#RequestMapping(value="example.htm", method = RequestMethod.POST)
#ModelAttribute("msg")
public String doingPost(#RequestParam(value="name") String name){
System.out.println(name);
return "successfully Posted";
}
I have developed admin app with AngularJS and JAVA as server side Restfull API, I want now that if the user tape a wrong login/password couple , I want to handle the error and show a message in the client side page , here is my code:
#RequestScoped
#Path("auth")
public class LoginResource {
#Inject
private UserServiceLocal userServiceLocal;
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response authenticate(Credentials credentials) {
User userLoggedIn = userServiceLocal.authenticate(
credentials.getUsername(), credentials.getPassword());
if (userLoggedIn != null) {
userServiceLocal.setToken(userLoggedIn, TokenUtils.createToken());
return Response.ok(userLoggedIn).build();
} else {
return Response.status(Response.Status.UNAUTHORIZED).build();
}
}
}
and this is my client side code :
function login(username, password) {
var deferred = $q.defer();
$http
.post(auth_uri, {
username: username,
password: password
})
.then(
function(response) {
if(response){
userInfo = {
accessToken: response.data.token
};
$window.sessionStorage["token"] = response.data.token;
$rootScope.token = response.data.token;
deferred.resolve(response);
}
},
function(error) {
deferred.reject(error);
});
return deferred.promise;
};
and here when I consume the login service :
function LoginController($scope, $state, authenticationSvc){
$scope.submit = function(credentials) {
authenticationSvc
.login(credentials.username, credentials.password)
.then(
function(response) {
$state.go('dashboard.home');
console.log(response.status);
}, function(error) {
console.log('error.status : ' + error.status)
});
}
};
the problem is when I try to issue an error to test the error response, I have the error showed on the console of the browser, but not caught in the error callbackof the promise, what is wrong please ?
You forgot the return statement in your $http callbacks. Or as suggested in comment you can just return the result of $http to simplify (it is already a promise).
...function(error) { return deferred.reject(error);});
I'm calling a method inside my Web Api 2 controller, passing in a model called login which consists of EmailAddress and Password. However it hits the method but the model passed in is always null...
My call from AngularJs function :
var login = { "EmailAddress": emailAddress, "Password": password };
$http.post("/api/Login/", { headers: { 'RequestVerificationToken': $scope.antiForgeryToken } }, login).success(function () {
alert('succes');
}).error(function () {
alert('Unable to login at present, please try again later');
});
My method:
[ValidateAntiForgeryToken]
public void Post([FromBody]Login login)
{
var t = login.EmailAddress;
}
I think its something to do with how I've structure my actual Angular $http.post method but again I'm not sure, can anyone suggest would could potentially be wrong with it?
Can you use ajax and Razor?
var login = { "EmailAddress": emailAddress, "Password": password };
$.ajax({
url: "#Url.Action("api/login", "Controller", login)",
type: "GET",
data: {},
success: fCheckBoxes
});
Why cannot add the token to every request by configuring your app.js
// Set header for every request
app.factory('httpRequestInterceptor', function ($localStorage) {
return {
request: function (config) {
if ($localStorage.token != null)
config.headers['myAppToken'] = $localStorage.token;
return config;
}
};
});
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('httpRequestInterceptor');
});
I'm trying to send the post request to server with post data
it's sent the request to the server, but not in right format
request url like /rest/api/modifyuser/?currentPassword=admin&newPassword=admin
it's like GET request - (may be this is problem)
I'm new to angularjs . please share idea to solve this problem
Here is my code
In controller
var currentPass = "admin";
var newPass = "admin";
var confirmPass = "admin";
var authToken = "abcdef";
User.changePassword(currentPass, newPass, confirmPass, authToken, function(response) {
angular.forEach(response, function (item) {
alert("resp"+ item);
});
});
In services
UIAppResource.factory('User', function($resource) {
return {
changePassword: function(currentPass, newPass, confirmPass, authtoken, callback) {
var Resq = $resource(baseURL + "modifyuser", {}, {
'query': {
method: 'POST',
params: {
'currentPassword': currentPass,
'newPassword': newPass,
'confirmPassword': confirmPass
},
headers: {
'Accept':'application/json',
'Content-Type':'application/json',
'X-Internal-Auth-Token': authtoken
},
isArray: false
}
});
Resq.query(callback);
}
};
});
Thanks in advance
I dont want to say you are doing it all wrong.. but you are def. abusing things. The default way to POST something with ng-resource is to use save. Second, the default way to send data is to instantiate a $resource factory with the data you want. See _resource below. We pass the data we want, and it will automagically convert it and if its a POST send it in the body, or in the case of a GET it will turn into query parameters.
UIAppResource.factory('User', function($resource) {
return {
changePassword: function(currentPass,
newPass,
confirmPass,
authtoken,
callback
) {
var Resq = $resource(baseURL + "modifyuser", {}, {
'save': {
method: 'POST',
headers: {
'Accept':'application/json',
'Content-Type':'application/json',
'X-Internal-Auth-Token': authtoken
}
}
});
var _resource = new Resq({
'currentPassword': currentPass,
'newPassword': newPass,
'confirmPassword': confirmPass
});
_resource.$save(callback);
}
};
});