I am trying to login and make a post to my project on my web host. I have removed the cors issue by adding the cors attribute to my web api 2 controller and my WebApiConfig.cs file. When I make a post with my login information included my console.log message shows the html of my login.cshtml file that is on my web host. And the "Job" information I am trying to post is not being posted as well.
Angular Controller
$scope.submitJob = function () {
var data = {
username: $scope.currentItem.username,
password: $scope.currentItem.password,
JobId: $scope.JobId,
JobNumber: $scope.currentItem.JobNumber,
JobName: $scope.currentItem.JobName,
}
var json = JSON.stringify(data);
// json is the json data you need to post
$http.post('http://www.example.com/api/apiJob', json, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' } })
.success(function (data, status) {
console.log(data);
})
.error(function (data, status) {
// error code
});
};
Web Api 2 Controller
[Authorize]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class apiJobController : ApiController
{
// GET api/<controller>
[AllowAnonymous]
public IEnumerable<JobResult> Get()
{
using (var context = new ApplicationDbContext())
{
return context.Jobs
.ToResults();
}
}
// GET api/<controller>/5
public Job GetJob(int? id)
{
using (var context = new ApplicationDbContext())
{
Job model = new Job();
model = context.Jobs
.FirstOrDefault(j => j.JobId == id);
return model;
}
}
// POST api/<controller>
public async Task<IHttpActionResult> PostnewJob([FromBody]JobViewModel newJob)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
using (var context = new ApplicationDbContext())
{
var job = new Job();
Mapper.CreateMap<JobViewModel, Job>();
Mapper.Map(newJob, job);
context.Jobs.Add(job);
await context.SaveChangesAsync();
return CreatedAtRoute("JobApi", new { job.JobId }, job);
}
}
Screenshot
Related
Problem :
API controller cannot access HTTP request data which are included FormData object in HTTP request
I need to pass file object data appended in FormData Object in http Post request to asp.net api controller and front-end is angularjs.i can not retrieve http request data from api controller.my code is below. please look into this, it would be great :)
when i pass,
Content-type : undefined
the error says 415 Unsupported Media Type
if Content-type: multipart/form-data then cannot access data from API controller.
Front-end
$scope.submit = function (files) {
var formData = new FormData();
var getFormData = function(appendFiles){
if (appendFiles.length) {
angular.forEach(appendFiles,function(file){
if(!file.uploaded){
formData.append("imgFiles",file);
file.uploaded = true;
}
});
} else {
formData.append('imgFiles', files);
}
console.log(formData.values());
return formData;
}
$http({
url : "URL",
method: "POST",
data: getFormData(files),
headers: {
'Content-Type': undefined
},
transformRequest: angular.identity,
})
.then(
function (resp) {
// alert(JSON.stringify(resp));
console.log(resp)
},
function (resp) {
console.log(resp)
}
);
};
Api controller Method
[HttpPost]
[Route("route")]
public string UploadFiles(List<HttpPostedFileBase> files)
{
var filesToDelete = HttpContext.Current.Request.Files;
//i need to access file here.using param or otherway
return stat;
}
I have solved the problem.i have changed the api controller method as below,
[HttpPost]
[Route("route")]
public async Task<string> UploadFiles()
{
FileUploadService fileService = new FileUploadService();
if (!Request.Content.IsMimeMultipartContent())
{
this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
var uploadFolder = "upload folder physical path"
//this method is in below
var provider = GetMultipartProvider(uploadFolder);
await Request.Content.ReadAsMultipartAsync(provider);
foreach (MultipartFileData fileData in provider.FileData)
{
var physicalPath = fileData.LocalFileName;
var fileName = fileData.Headers.ContentDisposition.FileName;
}
return "return value";
}
private MultipartFormDataStreamProvider GetMultipartProvider(string uploadFolder)
{
try
{
var root = HttpContext.Current.Server.MapPath(uploadFolder);
if (!Directory.Exists(root))
{
Directory.CreateDirectory(root);
}
return new MultipartFormDataStreamProvider(root);
}
catch (Exception ex)
{
throw ex;
}
}
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!');
});
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 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;
});
};