Angular $http.post 1.6.1 not passing data to WebAPI - angularjs

All, I just created a new Angular package using 1.6.1 but now the data doesn't seem to pass to my WebAPI. However, when I post bits via SoapUI or something like that, everything is fine.
The Javascript looks like this:
function testapi()
{
var serviceRoot='http://server/testangular16/api/Values';
var deferred=$q.defer();
var req = {
method: 'POST',
url: serviceRoot,
data: 'PassInTheText'
};
$http(req).then(goodResponse,badResponse);
return deferred.promise;
};
function goodResponse(response)
{
console.log("Good response");
console.log(response);
}
function badResponse(response)
{
console.log("Bad response");
console.log(response);
}
and the webapi is a very simple C# controller:
// POST api/values
public HttpResponseMessage Post([FromBody]string value)
{
HttpResponseMessage rp = new HttpResponseMessage(HttpStatusCode.OK);
rp.Content = new StringContent(value);
return rp;
}
I am making it into the controller, I can set a break point and hit the parts where I can look at the value. It's always null.
Looking at the network trace, the angular part does do a preflight and I can see the 200 response back.
Request URL:http://server/testangular16/api/Values
Request Method:OPTIONS
Status Code:200 OK
Remote Address:10.7.14.209:80
**Response Headers view source**
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:content-type
Access-Control-Allow-Origin:http://localhost:8000
Cache-Control:no-cache
Content-Length:0
Date:Fri, 03 Feb 2017 18:09:04 GMT
Expires:-1
Pragma:no-cache
Server:"Management Corporation"
X-AspNet-Version:4.0.30319
**Request Headers view source**
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:mjvzrx3
Origin:http://localhost:8000
Referer:http://localhost:8000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36
So, it looks like I'm passing CORS, but when I get to trying to pass the data in as the content of the post, it doesn't make it.
Any ideas what I'm missing?
Thanks,
Nick

Web API expects an object in the message body, you cant pass in a primitive type unless you use application/x-www-form-urlencoded as the content-type and prefix the value with an equals = sign.
So you can fix it by one of these methods
Adjust the c# parameter and turning it into a type that has a string property and then send in a json object with a matching parameter name.
Change the request to url-encoding content type and add a = to the variable value.
Send it as a part of the URL instead of the message body, you can still use the POST method.
Change to form-urlencoded
function testapi()
{
var serviceRoot='http://server/testangular16/api/Values';
var deferred=$q.defer();
var req = {
method: 'POST',
url: serviceRoot,
data: '=PassInTheText', // added =
contentType: 'application/x-www-form-urlencoded' // specify content type
};
$http(req).then(goodResponse,badResponse);
return deferred.promise;
};

It seems if I do this, it works as expected.... Thoughts?
// POST api/values
public HttpResponseMessage Post(HttpRequestMessage request)
{
var data = request.Content.ReadAsStringAsync().Result;
Console.WriteLine("Data: {0}", data);
HttpResponseMessage rp = new HttpResponseMessage(HttpStatusCode.OK);
rp.Content = new StringContent("Data back from WebAPI" + data);
return rp;
}

Related

Http POST 405 errror in Angularjs with Spring MVC

Actually I want to integrate Spring with Angularjs and i am beginner in Angularjs. When i use $http post method it return POST 405.Here is my code
SignUp.html
<form method="post" ng-submit="saveUser()">
<input type="hidden" name="${_csrf.parameterName}"
value="${_csrf.token}" />
</form>
myApp.js
var myApp = angular.module('myApp', ['ngMessages']);
UserIdController.js
myApp.controller('UserIdController', [
'$scope',
'UserIdService',
function($scope, UserIdService) {
$scope.saveUser = function() {
UserIdService.saveUser($scope.user).then(
function success(response) {
console.log("user Added");
}, function error(response) {
console.log("User not Added")
});
}
} ]);
UserIdService.js
myApp
.service(
'UserIdService',
[
'$http',
function($http) {
this.saveUser = function saveUser(user) {
return $http({
method : 'post',
url : 'SignUpUser',
data : {
firstName : user.firstName
},
headers : 'Content-Type: application/json'
});
}
} ]);
Spring REST Controller
#RestController
#Produces("text/plain")
public class SignUpController {
private static final Logger logger =
LogManager.getLogger(SignUpController.class);
#RequestMapping(value = "/SignUpUser", method =
RequestMethod.POST, headers = "Accept=application/json")
public String saveUser(#PathVariable String firstname) throws
ParseException {
logger.debug("Enter in SignUp Controller in Post Method");
UserDetails userDetails = new UserDetails();
studentDetails.setFirstName(firstname);
return "ok";
}
I got this error in Chrome in Inspect element
Request URL:http://localhost:8080/examapp/signup
Request Method:POST
Status Code:405
Remote Address:[::1]:8080
Referrer Policy:no-referrer-when-downgrade
Response Headers
view parsed
HTTP/1.1 405
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-XSS-Protection: 1; mode=block
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Allow: GET
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en
Content-Length: 1084
Date: Fri, 04 Aug 2017 05:50:32 GMT
Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, br
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:26
Content-Type:application/json
Cookie:JSESSIONID=ACF3E30CB7B3A6A9862F923F42DB61B5
Host:localhost:8080
Origin:http://localhost:8080
Referer:http://localhost:8080/examapp/signup.html
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36
Request Payload
Does anyone have an idea of what I'm doing wrong? It seems like a pretty straight forward implementation that is working on all of the tutorials I've seen yet. Any help will be appreciated. Thank you.
Please add #RequestMapping("/examapp") over yourSignUpController
#RestController
#Produces("text/plain")
#RequestMapping("/examapp")
public class SignUpController {
You have specified #PathVariable here. A path variable is just that, a variable from the path. What you want is #RequestBody.
In your scenario, Spring has nothing maped to /SignUpUser, it is looking for /SignUpUser/{firstName}, but since #RequestMapping doesn't specify {firstName}, you are essentially posting to a non-existent resource.
Although unrealistic in the real world, to post just a first name to login, In your $http.post, you would just want data : user.firstName.
In your Spring controller:
#RequestMapping(value = "/SignUpUser", method =
RequestMethod.POST, headers = "Accept=application/json")
public String saveUser(#RequestBody String firstname)
The Right Fix
If you want your back-end to accept what you have in Angular (more real-world), you would create a POJO class, and accept that (#RequestBody UserDetails request). It appears you have the UserDetails POJO created, so you just have to accept that instead:
#RequestMapping(value = "/SignUpUser", method =
RequestMethod.POST, headers = "Accept=application/json")
public String saveUser(#RequestBody UserDetails userDetails ) {

web api returning html instead of json

I've created an asp.net core project and in the project I have an angularjs application and also a web api project. The angularjs application loads when I login via postman I get the response I expect in json. But when I try the same in angularjs I get the response in html.
I've tried quite a few settings but unable to get this working.
Tried setting the $http services header, and $httpProvider header but unable to get this working in angular js.
I set the content-type in postman to application/json and it works so not think its because the content-type is wrong in angular js.
Startup.cs file:
public void ConfigureServices(IServiceCollection services)
{
services
.AddMvcCore()
.AddJsonFormatters();
// Add framework services.
services.AddMvc().AddJsonOptions(
options =>
options.SerializerSettings.ContractResolver = new
CamelCasePropertyNamesContractResolver()
);
The controller in web api is:
[Route("test3")]
[HttpPost]
public JsonResult Test3([FromBody]LoginUserRequest model)
{
LoginUserResponse response = new LoginUserResponse();
response.validLogin = false;
response.Message = "failed" + model.Email;
return Json(response);
}
Angular js service:
vm.getLogin = getLogin;
function getLogin(request) {
return $http.post('/webapi/account/test3',request,{
headers: { 'Content-Type': 'application/json; charset=utf-8'}
})
.then(getLoginComplete)
.catch(getLoginFailed);
}
function getLoginComplete(data, status, headers, config) {
return data.data;
}
function getLoginFailed(e) {
var newMessage = 'XHR Failed for login';
if (e.data && e.data.description) {
newMessage = newMessage + '\n' + e.data.description;
}
e.data.description = newMessage;
return {"error":true, "message":"Unable to login please try again later"};
}
Chrome network via developer tools:
Request URL:http://localhost:5000/webapi/account/test3
Request Method:POST
Status Code:200 OK
Remote Address:[::1]:5000
Referrer Policy:no-referrer-when-downgrade
Response Headers
view source
Content-Type:text/html; charset=utf-8
Date:Tue, 11 Jul 2017 19:58:46 GMT
Server:Kestrel
Transfer-Encoding:chunked
Request Headers
view source
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate, br
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6
Connection:keep-alive
Content-Length:61
Content-Type:application/json; charset=UTF-8
Host:localhost:5000
Origin:http://localhost:5000
Referer:http://localhost:5000/login

spring RESTcontroller to accept dataURI

I am running into a issue of using angularjs ng-img-crop and Spring-boot REST web service.I want to upload an image file from ng crop to my backend web service.
I tried writing a spring controller but it failed and I couldnt find a good tutorial for this. help me resolve this basic request.
Thanks !!!
app.js
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version',
'ngImgCrop'
])
.controller('Ctrl',['$scope','notify', function($scope,notify) {
$scope.myImage='';
$scope.myCroppedImage='';
var handleFileSelect=function(evt) {
var file=evt.currentTarget.files[0];
var reader = new FileReader();
reader.onload = function (evt) {
$scope.$apply(function($scope){
$scope.myImage=evt.target.result;
});
};
reader.readAsDataURL(file);
};
angular.element(document.querySelector('#fileInput')).on('change',handleFileSelect);
$scope.submit=function() {
notify($scope.myCroppedImage);
};
}]).
factory('notify',['$http', function($http) {
return function(myCroppedImage) {
var name = 'vishnu';
$http.post('http://localhost:8080/imageUpload', myCroppedImage)
.success(function(data, status, headers, config) {
alert("success");
})
.error(function(data, status, headers, config) {
alert("fail");
});
}
}])
controller.java
#RequestMapping(value="/imageUpload",method=RequestMethod.POST)
#ResponseBody
public String imageUpload(#RequestBody MultipartFile data){
return "success";
}
when I run with the following request, I got some exception in the web service.
Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/imageUpload
Request Method:POST
Status Code:500 Internal Server Error
Request Headersview source
Accept:application/json, text/plain, /
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:1850
Content-Type:application/json;charset=UTF-8
Host:localhost:8080
Origin:file://
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36**
Request payload
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAFIklEQVR4Xu3VsRHAMAzEsHj/pTOBXbB9pFchyLycz0eAwFXgsCF.......
Response header
Connection:close
Content-Type:application/json;charset=UTF-8
Date:Fri, 24 Apr 2015 12:40:35 GMT
Server:Apache-Coyote/1.1
Transfer-Encoding:chunked
Exception in java
org.springframework.web.multipart.MultipartException: The current request is not a multipart request
First of all your controller should looks like:
public ResponseEntity<Response> fileUpload(#RequestParam("file") MultipartFile file) {
Use #RequestParam instead of #RequestBody, and send the file in a parameter with the same name you're using in the annotation.
Moreover, your request should be sent with type multipart/form-data. For example, a common html for would be:
<form method="POST" enctype="multipart/form-data" action="your url">

Getting Form Data From Outcoming HTTP POST response in Angular js

I am trying to develop payment module with angularjs and asp.net web api.
I am using an payment api (iyzico).
With that api I create shopping token request and this request return an js script response and a shopping token.
I load this js file and payment form is generated by returning js file.
After generating payment form, I entered my credit card infos and send these infos to payment api then payment api return response but I could not get this response from page (This response come when page is loading).
Http Get method for generating shopping token in payment.js
function loadDetails() {
$http.get( '/API/api/profile/GetPaymentToken').then(function (results) {
$scope.paymentData = jQuery.parseJSON(results.data);
$scope.code_snippet = $sce.trustAsHtml($scope.paymentData.code_snippet);
var paymentScriptUrl = "https://www.iyzico.com/frontend/form/v1/widget.js?mode=test&token=" + $scope.paymentData.transaction_token;
$.ajax({
url: paymentScriptUrl,
dataType: "script",
cache: true,
success: function (data, textStatus, jqXHR) {
var f = new Function(data);
f();
iyzi_jQuery(this).iyziPayment({
host: 'https://iyziconnect.com/pay-with-transaction-token/',
mode: 'test',
assetsURL: 'https://www.iyzico.com/frontend/form/v1/',
installment: '0',
language: 'tr'
});
},
error: function (jqXHR, status, err) {
console.log("");
}
});
},
function (response) { // optional
_helper.error.handleError(toaster, response.data, response.status);
})
}
Token Generator in Web.Api, it is called in payment.js
[Authorize]
[HttpGet]
[Route("GetPaymentToken")]
public async Task<IHttpActionResult> GetPaymentToken()
{
System.Diagnostics.Debugger.Break();
WebRequest request = WebRequest.Create("https://api.iyzico.com/v2/create");
request.Method = "POST";
var rand = new Random();
var external_id = rand.Next(0, 100000000);
string postData = "api_id=my_id"
+ "&secret=my_secret"
+ "&external_id=" + external_id.ToString()
+ "&mode=test"
+ "&type=CC.DB"
+ "&return_url=http://localhost:2020/payment2" //returning url
+ "&amount=10020"
+ "&currency=TRY"
+ "&descriptor=PAYMENT_DESCRIPTION"
+ "&customer_contact_ip=CUSTOMER_IP"
+ "&customer_language=tr"
+ "&installment=false";
byte[] byteArray = System.Text.Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
System.IO.Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
dataStream = response.GetResponseStream();
System.IO.StreamReader reader = new System.IO.StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
return Ok(responseFromServer);
After getting shopping token I enter my credit card infos and send form to external payment api and external api return information to my return url (http://localhost:2020/payment2) about my payment is successful or failed .
I can see returning responce from external api at chrome developer tools > network actions but I can not get that form data from mycontroller js file. returning response is at below
Remote Address:[::1]:2020
Request URL:http://localhost:2020/payment2
Request Method:POST
Status Code:200 OK
Response Headers
view source
Cache-Control:private
Content-Length:11337
Content-Type:text/html
Date:Fri, 03 Apr 2015 08:45:22 GMT
Server:Microsoft-IIS/8.5
X-Powered-By:ASP.NET
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate
Accept-Language:en-GB,en-US;q=0.8,en;q=0.6,tr;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Content-Length:532
Content-Type:application/x-www-form-urlencoded
Cookie:countrySCJS=TR; ootdcuSCJS=34602; ootdchSCJS=10742; ctxjs1420m06d05=7b2273756363657373223a302c226c6f675f616374697665223a317d; ASPSESSIONIDQCDBDRBQ=BKGJHHKCKDDLJCBBPMPJJHFH; ASPSESSIONIDQAADBTBR=AMPJDALCPFGILMAOKEDMMGBP; ASPSESSIONIDSCAADQAR=GKKFJCCDLILKPNHAEHBHHLHJ
Host:localhost:2020
Origin:null
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36
Form Data
view source
view URL encoded
**json:{"response":{"state":"failed","date_time":"15-04-03 08:43:24","error_code":"800.100.154","error_message":"transaction marked as invalid","error_message_tr":""},"transaction":{"transaction_id":"MTQyODA1MDU4NAnrin0vdEV06f4hWARX","external_id":"23583443","reference_id":"____________20150403084323.653059Kq","state":"rejected","connector_type":"Isbank","installment_count":0}}**
How can I get that json named array?
You have to sacrifice your your single page application for callback.
Get callback to your REST address
Process the POST parameters
Generate (return text/html) a simple SUCCESS of FAIL page. Let this page contain the result and link to appropriate page (main page url or payment page url)
Link should open your single page angularjs and your controller should display
appropriate page according to URL.

Cross origin communication between NGINX and spark Java

I am using NGINX and sparkjava for my web application. I am sure I have enabled all CORS headers properly. Still, I am getting "XMLHttpRequest cannot load http://localhost:3003/platformAPI/login. Invalid HTTP status code 404" error.Below mentioned are my client and server methods from extjs and spark java respectively. I have inspected the network tab of my browser to get the response and request headers sent as well. They are also mentioned below. Any help to let me know as to what's wrong with my approach is highly appreciated :)
Client method from Nginx:
function(button, event, options){
var form = Ext.getCmp("LoginformId").getForm();
if (form.isValid()) {
var userJson = JSON.stringify(form.getFieldValues());
form.submit({
url: 'http://localhost:3003/platformAPI/login',
//headers : {'Content-Type':undefined,},
//dataType: 'jsonp',
success: function(form, action) {
// Ext.Msg.alert('Success', action.result.msg);
var sessionID=action.result.sessionID;
var clientName=action.result.clientName;
sessionStorage.setItem('sessionID',sessionID);
sessionStorage.setItem('clientName',clientName);
window.location="http://localhost:3000/";
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
}
});
}
}
Server Methods:
filter to enable CORS headers (Calling this in main)
private static void enableCORS(final String origin, final String methods, final String headers) {
before(new Filter() {
#Override
public void handle(Request request, Response response) {
response.header("Access-Control-Allow-Origin",request.headers("origin"));
response.header("Access-Control-Allow-Headers", "Origin, x-requested-with, content-type, Accept");
response.header("Access-Control-Request-Method", "GET,PUT,POST,DELETE,OPTIONS");
);
}
});
}
Login method:
post("platformAPI/login", "undefined",
(request, response) -> {
System.out.print("inside login");
JSONObject object1 = new JSONObject();
response.body(object1.put("success", true).toString());
return response;
});
Request and response headers:
Remote Address:127.0.0.1:3003
Request URL:http://localhost:3003/platformAPI/login
Request Method:OPTIONS
Status Code:404 Not Found
Response Headers
view source
Access-Control-Allow-Headers:Origin, x-requested-with, content-type, Accept
Access-Control-Allow-Origin:http://localhost:3000
Access-Control-Request-Method:GET,PUT,POST,DELETE,OPTIONS
Cache-Control:must-revalidate,no-cache,no-store
Content-Length:295
Content-Type:text/html; charset=ISO-8859-1
Server:Jetty(9.0.2.v20130417)
Request Headers
view source
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Request-Headers:x-requested-with, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:3003
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.89 Safari/537.36
Try enable CORS in Spark-Java with the following snippet:
options("/*",
(request, response) -> {
String accessControlRequestHeaders = request
.headers("Access-Control-Request-Headers");
if (accessControlRequestHeaders != null) {
response.header("Access-Control-Allow-Headers",
accessControlRequestHeaders);
}
String accessControlRequestMethod = request
.headers("Access-Control-Request-Method");
if (accessControlRequestMethod != null) {
response.header("Access-Control-Allow-Methods",
accessControlRequestMethod);
}
return "OK";
});
before((request, response) -> {
response.header("Access-Control-Allow-Origin", "*");
});
Provided you must consider this point as well.
It will works with Postman because you are directly calling the server. There is no CORS involved here. But when you do it through javascript or angular etc.. CORS comes into play. So the requested url doesn't contain http scheme. You need to change localhost:portNumber/login to http://localhost:portNumber/login

Resources