AngularJS Post data as key-value pair to a asp.net page - javascript

I am trying to post key-value pair data from angular application to a asp.net page however I am not able to receive the result at the asp.net page.
Example Data
{fullName: "Vikas Bansal", userId: "1001387693259813", userimageurl: "http://graph.facebook.com/1001387693259813/picture?width=250&height=250"}
Angular Code
var postData = {
fullName: $scope.name,
userId: $scope.userId,
userimageurl: $scope.userImage
};
var postUrl = 'http://localhost:41115/Index.aspx';
$http({
url: postUrl,
method: "POST",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: postData
}).then(function (responce) {
console.log(responce);
}, function (responce) {
console.log(responce);
});
Asp.net Page Code
protected void Page_Load(object sender, EventArgs e)
{
var userId = Request.Form["userId"]; /// getting null
var fullName = Request.Form["fullName"]; /// getting null
var img = Request.Form["userimageurl"]; /// getting null
}
In asp.net page all variables are null.
EDIT
By changing content type to 'Content-Type': 'application/json; charset=utf-8' in angularJs post request
and by using var strJSON = (new StreamReader(Request.InputStream).ReadToEnd()); I am able get the posted json
but I am still wondering if there is a way to get key-value pairs directly?
like this var userId = Request.Form["userId"];

It's because your payload is actually JSON but you tried to pass as a FormData object.
You'll need to make a FormData() object. Then
(1) Tell AngularJs not to serialize it by using the angular.identity function.
(2) Angular's default header for PUT and POST requests is application/json, so you'll want to override that too. The browser sets the Content-Type to multipart/form-data and fills in the correct boundary.
Try this:
var postData = new FormData();
postData.append("fullName", $scope.name);
postData.append("userId", $scope.userId);
postData.append("userimageurl", $scope.userImage);
$http.post(postUrl, postData, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined }
}).then(function(data) {
//success
}, function(error) {
//error
});

Related

AngularJs use object in post

I'm trying to pass a json object to my factory.login method so I can re use it.
This is my code:
Controller function
var data = {email:'test','password':'test'};
vm.login = function() {
employeeFactory.login(vm.url, vm.data)
.then(function(response) {
console.log(response);
}, function(data)
{
console.log(data.status);
});
}
Factory
factory.login = function(url,data) {
return $http({
'method': 'POST',
'url': url,
'data': $.param(
data
),
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
return factory;
But the error is:
angular.js:13294 TypeError: Cannot read property 'jquery' of undefined
at Function.n.param (jquery-2.2.2.min.js:4)
at Object.factory.login (employeeFactory.js:14)
at employeeController.vm.login (employeeController.js:16)
at fn (eval at <anonymous> (angular.js:14138), <anonymous>:4:285)
at b (angular.js:15151)
at e (angular.js:24674)
at m.$eval (angular.js:16895)
at m.$apply (angular.js:16995)
at HTMLButtonElement.<anonymous> (angular.js:24679)
at HTMLButtonElement.n.event.dispatch (jquery-2.2.2.min.js:3)
This should be vm.data
vm.data = {email:'test','password':'test'};
And factory doesn't require jQuery at all, just use below construction
factory.login = function(url,data) {
return $http({
'method': 'POST',
'url': url,
//don't use $.param, as you need jQuery dependency for that
//for x-www-form-urlencoded you have to use this construction
//email=test&password=test
'data': 'email=' + data.email + '&password=' + data.password,
'headers': {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
}
return factory;
But consider using JSON type on server request handler, as it's much easier
Your JSON seems incorrect. Should be:
var data = { "email": "test", "password": "test"};
Also the $http.post function is available:
$http.post(url, data, [{headers: { 'Content-Type' : 'application/x-www-form-urlencoded'}]);
JSON is a format to serialize object, so it's a string.
You have your object as data that contains the data to be sent to the server, so just do this:
Just put your data object in it:
factory.login = function(url,data) {
return $http({
'method': 'POST',
'url': url,
'data': data
});
}
return factory;
Angular will send json to the server in the payload. You don't need to do that serialization your self.
Documentation https://docs.angularjs.org/api/ng/service/$http
-> Default Transformations ->
Request transformations ($httpProvider.defaults.transformRequest and
$http.defaults.transformRequest):
If the data property of the request configuration object contains an
object, serialize it into JSON format. Response transformations
($httpProvider.defaults.transformResponse and
$http.defaults.transformResponse):
If XSRF prefix is detected, strip it (see Security Considerations
section below). If JSON response is detected, deserialize it using a
JSON parser.
The stack trace show the following error :
TypeError: Cannot read property 'jquery' of undefined
miss match variable uses declared var data = {} but used vm.data in your controller. should declare as
vm.data= {email:'test','password':'test'}
or
use data in employeeFactory.login(vm.url, data) if declare as var data= {}
and in your factory no need to use $.param can send as argument in post method like
$http.post(url, data, [{headers: { 'Content-Type' : 'application/x-www-form-urlencoded'}]);
Angular Documentation

AngularJS: Get $http.post data in JSP

I wrote the below code to send the $http.post request
$http({
url: '/OA_HTML/ReportColumnSelection.jsp',
method: 'POST',
data: JSON.stringify({myData : $scope.reportColumns}),
headers: {'Content-Type': 'application/json;charset=utf-8'}
})
.success(function(response){
$scope.viewColumns = response.columnData;
})
.error(function(response){
//Error Log
console.log('Inside saveReportColumns Error');
});
Now the problem is i'm unable to get the "myData" JSON in ReportColumnSelection.jsp
request.getParameter("myData");
Please let me know if i'm doing anything wrong.
AngularJS Version 1.4.7
Code to save report columns:
$scope.saveReportColumns = function () {
console.log('Inside saveReportColumns');
$http({ url: '/OA_HTML/eis/jsp/reporting/reports/newreport/columnselection/EISRSCReportColumn‌​SelectionAM.jsp',
method: 'POST',
data: JSON.stringify({myData:$scope.reportColumns}),
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
}).success(function(response){}).error(function(response){
//Error Log console.log('Inside saveReportColumns Error');
});
};
The $http services default content type is application/json, which your JSP cannot parse.
You can either,
change the content type of the request to application/x-www-form-urlencoded;charset=utf-8 (which might have other implications)
or
read it as a stream like below.
InputStream body = request.getInputStream();
It might be a good idea to leave the content type as it is, and instead read the request body and parse it with a library such as google/json
BufferedReader reader = request.getReader();
Gson gson = new Gson();

Angular js passing values from form to php [duplicate]

In the code below, the AngularJS $http method calls the URL, and submits the xsrf object as a "Request Payload" (as described in the Chrome debugger network tab). The jQuery $.ajax method does the same call, but submits xsrf as "Form Data".
How can I make AngularJS submit xsrf as form data instead of a request payload?
var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};
$http({
method: 'POST',
url: url,
data: xsrf
}).success(function () {});
$.ajax({
type: 'POST',
url: url,
data: xsrf,
dataType: 'json',
success: function() {}
});
The following line needs to be added to the $http object that is passed:
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
And the data passed should be converted to a URL-encoded string:
> $.param({fkey: "key"})
'fkey=key'
So you have something like:
$http({
method: 'POST',
url: url,
data: $.param({fkey: "key"}),
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})
From: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ
UPDATE
To use new services added with AngularJS V1.4, see
URL-encoding variables using only AngularJS services
If you do not want to use jQuery in the solution you could try this. Solution nabbed from here https://stackoverflow.com/a/1714899/1784301
$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: xsrf
}).success(function () {});
I took a few of the other answers and made something a bit cleaner, put this .config() call on the end of your angular.module in your app.js:
.config(['$httpProvider', function ($httpProvider) {
// Intercept POST requests, convert to standard form encoding
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
var key, result = [];
if (typeof data === "string")
return data;
for (key in data) {
if (data.hasOwnProperty(key))
result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
return result.join("&");
});
}]);
As of AngularJS v1.4.0, there is a built-in $httpParamSerializer service that converts any object to a part of a HTTP request according to the rules that are listed on the docs page.
It can be used like this:
$http.post('http://example.com', $httpParamSerializer(formDataObj)).
success(function(data){/* response status 200-299 */}).
error(function(data){/* response status 400-999 */});
Remember that for a correct form post, the Content-Type header must be changed. To do this globally for all POST requests, this code (taken from Albireo's half-answer) can be used:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
To do this only for the current post, the headers property of the request-object needs to be modified:
var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer(formDataObj)
};
$http(req);
You can define the behavior globally:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
So you don't have to redefine it every time:
$http.post("/handle/post", {
foo: "FOO",
bar: "BAR"
}).success(function (data, status, headers, config) {
// TODO
}).error(function (data, status, headers, config) {
// TODO
});
As a workaround you can simply make the code receiving the POST respond to application/json data. For PHP I added the code below, allowing me to POST to it in either form-encoded or JSON.
//handles JSON posted arguments and stuffs them into $_POST
//angular's $http makes JSON posts (not normal "form encoded")
$content_type_args = explode(';', $_SERVER['CONTENT_TYPE']); //parse content_type string
if ($content_type_args[0] == 'application/json')
$_POST = json_decode(file_get_contents('php://input'),true);
//now continue to reference $_POST vars as usual
These answers look like insane overkill, sometimes, simple is just better:
$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
"&password=" + encodeURIComponent(password) +
"&grant_type=password"
).success(function (data) {
//...
You can try with below solution
$http({
method: 'POST',
url: url-post,
data: data-post-object-json,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for (var key in obj) {
if (obj[key] instanceof Array) {
for(var idx in obj[key]){
var subObj = obj[key][idx];
for(var subKey in subObj){
str.push(encodeURIComponent(key) + "[" + idx + "][" + encodeURIComponent(subKey) + "]=" + encodeURIComponent(subObj[subKey]));
}
}
}
else {
str.push(encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]));
}
}
return str.join("&");
}
}).success(function(response) {
/* Do something */
});
Create an adapter service for post:
services.service('Http', function ($http) {
var self = this
this.post = function (url, data) {
return $http({
method: 'POST',
url: url,
data: $.param(data),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
}
})
Use it in your controllers or whatever:
ctrls.controller('PersonCtrl', function (Http /* our service */) {
var self = this
self.user = {name: "Ozgur", eMail: null}
self.register = function () {
Http.post('/user/register', self.user).then(function (r) {
//response
console.log(r)
})
}
})
There is a really nice tutorial that goes over this and other related stuff - Submitting AJAX Forms: The AngularJS Way.
Basically, you need to set the header of the POST request to indicate that you are sending form data as a URL encoded string, and set the data to be sent the same format
$http({
method : 'POST',
url : 'url',
data : $.param(xsrf), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
});
Note that jQuery's param() helper function is used here for serialising the data into a string, but you can do this manually as well if not using jQuery.
var fd = new FormData();
fd.append('file', file);
$http.post(uploadUrl, fd, {
transformRequest: angular.identity,
headers: {'Content-Type': undefined}
})
.success(function(){
})
.error(function(){
});
Please checkout!
https://uncorkedstudios.com/blog/multipartformdata-file-upload-with-angularjs
For Symfony2 users:
If you don't want to change anything in your javascript for this to work you can do these modifications in you symfony app:
Create a class that extends Symfony\Component\HttpFoundation\Request class:
<?php
namespace Acme\Test\MyRequest;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;
class MyRequest extends Request{
/**
* Override and extend the createFromGlobals function.
*
*
*
* #return Request A new request
*
* #api
*/
public static function createFromGlobals()
{
// Get what we would get from the parent
$request = parent::createFromGlobals();
// Add the handling for 'application/json' content type.
if(0 === strpos($request->headers->get('CONTENT_TYPE'), 'application/json')){
// The json is in the content
$cont = $request->getContent();
$json = json_decode($cont);
// ParameterBag must be an Array.
if(is_object($json)) {
$json = (array) $json;
}
$request->request = new ParameterBag($json);
}
return $request;
}
}
Now use you class in app_dev.php (or any index file that you use)
// web/app_dev.php
$kernel = new AppKernel('dev', true);
// $kernel->loadClassCache();
$request = ForumBundleRequest::createFromGlobals();
// use your class instead
// $request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
Just set Content-Type is not enough, url encode form data before send.
$http.post(url, jQuery.param(data))
I'm currently using the following solution I found in the AngularJS google group.
$http
.post('/echo/json/', 'json=' + encodeURIComponent(angular.toJson(data)), {
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}).success(function(data) {
$scope.data = data;
});
Note that if you're using PHP, you'll need to use something like Symfony 2 HTTP component's Request::createFromGlobals() to read this, as $_POST won't automatically loaded with it.
AngularJS is doing it right as it doing the following content-type inside the http-request header:
Content-Type: application/json
If you are going with php like me, or even with Symfony2 you can simply extend your server compatibility for the json standard like described here: http://silex.sensiolabs.org/doc/cookbook/json_request_body.html
The Symfony2 way (e.g. inside your DefaultController):
$request = $this->getRequest();
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request->replace(is_array($data) ? $data : array());
}
var_dump($request->request->all());
The advantage would be, that you dont need to use jQuery param and you could use AngularJS its native way of doing such requests.
Complete answer (since angular 1.4). You need to include de dependency $httpParamSerializer
var res = $resource(serverUrl + 'Token', { }, {
save: { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }
});
res.save({ }, $httpParamSerializer({ param1: 'sdsd', param2: 'sdsd' }), function (response) {
}, function (error) {
});
In your app config -
$httpProvider.defaults.transformRequest = function (data) {
if (data === undefined)
return data;
var clonedData = $.extend(true, {}, data);
for (var property in clonedData)
if (property.substr(0, 1) == '$')
delete clonedData[property];
return $.param(clonedData);
};
With your resource request -
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
This isn't a direct answer, but rather a slightly different design direction:
Do not post the data as a form, but as a JSON object to be directly mapped to server-side object, or use REST style path variable
Now I know neither option might be suitable in your case since you're trying to pass a XSRF key. Mapping it into a path variable like this is a terrible design:
http://www.someexample.com/xsrf/{xsrfKey}
Because by nature you would want to pass xsrf key to other path too, /login, /book-appointment etc. and you don't want to mess your pretty URL
Interestingly adding it as an object field isn't appropriate either, because now on each of json object you pass to server you have to add the field
{
appointmentId : 23,
name : 'Joe Citizen',
xsrf : '...'
}
You certainly don't want to add another field on your server-side class which does not have a direct semantic association with the domain object.
In my opinion the best way to pass your xsrf key is via a HTTP header. Many xsrf protection server-side web framework library support this. For example in Java Spring, you can pass it using X-CSRF-TOKEN header.
Angular's excellent capability of binding JS object to UI object means we can get rid of the practice of posting form all together, and post JSON instead. JSON can be easily de-serialized into server-side object and support complex data structures such as map, arrays, nested objects, etc.
How do you post array in a form payload? Maybe like this:
shopLocation=downtown&daysOpen=Monday&daysOpen=Tuesday&daysOpen=Wednesday
or this:
shopLocation=downtwon&daysOpen=Monday,Tuesday,Wednesday
Both are poor design..
This is what I am doing for my need, Where I need to send the login data to API as form data and the Javascript Object(userData) is getting converted automatically to URL encoded data
var deferred = $q.defer();
$http({
method: 'POST',
url: apiserver + '/authenticate',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
transformRequest: function (obj) {
var str = [];
for (var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: userData
}).success(function (response) {
//logics
deferred.resolve(response);
}).error(function (err, status) {
deferred.reject(err);
});
This how my Userdata is
var userData = {
grant_type: 'password',
username: loginData.userName,
password: loginData.password
}
The only thin you have to change is to use property "params" rather than "data" when you create your $http object:
$http({
method: 'POST',
url: serviceUrl + '/ClientUpdate',
params: { LangUserId: userId, clientJSON: clients[i] },
})
In the example above clients[i] is just JSON object (not serialized in any way). If you use "params" rather than "data" angular will serialize the object for you using $httpParamSerializer: https://docs.angularjs.org/api/ng/service/$httpParamSerializer
Use AngularJS $http service and use its post method or configure $http function.

malformed JSON string Error while passing JSON from AngularJS

I am trying to pass JSON string in ajax request. This is my code.
NewOrder = JSON.stringify (NewOrder);
alert (NewOrder);
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: "mydata="+ NewOrder
};
$http(req)
.success(function (data, status, headers, config) {
alert ('success');
})
.error(function (data, status, headers, config) {
alert (status);
alert (data);
alert ('Error')
});
alert (NewOrder) gives -
{"ItemList":[{"ItemName":"Quality Plus Pure Besan 500 GM","Quantity":1,"MRP":"28.00","SellPrice":"25.00"}],"CustomerID":1,"DeliverySlot":2,"PaymentMode":1}
Which seems to be a valid JSON string.
But in script side I am getting following error. in this line
my $decdata = decode_json($cgi->param('mydata'));
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)")
Can please someone help me why i am getting this error?
$cgi->param('myData') returns the query param string 'mydata', which in your case is not sent.
You're posting the json data in the request body of your http post payload, and not as a query/form param. In that case, you'd need some other function to read the contents of the request body in your server-side script.
which happens to be:
my $data = $query->param('POSTDATA');
as described in here: http://search.cpan.org/~lds/CGI.pm-3.43/CGI.pm#HANDLING_NON-URLENCODED_ARGUMENTS
Also you should remove the "mydata=" from your json in the body you post, because http request payload bodies do not have parameter names (they're for query/form-params only).
Your end code should be like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: NewOrder
};
and the servers side:
my $decdata = decode_json($query->param('POSTDATA'));
I think it may be related to this issue: AngularJs $http.post() does not send data
Usually I would post data like this:
var req = {
url: '/cgi-bin/PlaceOrder.pl',
method: 'POST',
headers: { 'Content-Type': 'application/json'},
data: {"mydata" : NewOrder}
};
However I am assuming that you are expecting the data as request params from this:
my $decdata = decode_json($cgi->param('mydata'));
If that is the case then the linked SO question is what you are looking for.
Angular $http.post accepts two params as url and payload
var url = '/cgi-bin/PlaceOrder.pl';
var payLoad = {'myData' :JSON.stringify(NewOrder)};
$http.post(url, payLoad)
.success(function(data) {
console.log(success);
})
At the server side, while fetching the required json string from the request param and then desearlize the json as following:
$result = $cgi->param('myData');
my $decdata = decode_json($result);

How do I send a object using JavaScript to Spring Controller using json

I am making simple Spring MVC web application. In my application I want to send a object from front end to Spring controller method. But when I do this I am getting js error
500 (Internal Server Error)
I tried to find a good answer in internet but still could not find a good one.
My controller method is
#RequestMapping(value = "/add", method = RequestMethod.GET, consumes = { MediaType.APPLICATION_JSON_VALUE }, produces = { MediaType.APPLICATION_JSON_VALUE })
public #ResponseBody String addInventory(#RequestBody InventoryAddParam inventoryAddParam) {
log.info("addInventory");
ServiceRequest<InventoryAddParam> serviceRequest = convertAddParamtoServiceRequest(inventoryAddParam);
validate(inventoryAddParam);
inventoryService.addInventory(serviceRequest);
return "Inventory Added Succesfully";
}
inventoryAddParam is a Serializable object that contain only String parameters.
My JavaScript function to send object is
function sendDataTest() {
$.ajax({
url : "/GradleSpringMVC/inventory/add",
type : 'GET',
dataType : 'json',
data : JSON.stringify(populateTestObject()),
contentType : 'application/json',
mimeType : 'application/json'
}).done(function(data) {
// temGrid.addJSONData(data);
}).fail(function(error) {
// parseToPageAlerts(error.responseText);
}).always(function() {
// hideLoading()
});}
I am creating the addParam object to send as ajax call.
It create in function
function populateTestObject(){
var addParam = new InventoryAddParam();
addParam.inventoryId = "INV001";
addParam.name = "ECG MACHINE";
addParam.price = "1000";
addParam.hospital = "Colombo";
addParam.userNote = "User Note";
return addParam;}
Do I have done any wrong thing here ?
Other details about the error
Remote Address:127.0.0.1:8080
Request URL:http://localhost:8080/GradleSpringMVC/inventory/add
Request Method:POST
Status Code:500 Internal Server Error
Header
Connection:close
Content-Language:en
Content-Length:4939
Content-Type:text/html;charset=utf-8
Date:Wed, 21 Jan 2015 03:55:19 GMT
Server:Apache-Coyote/1.1
You spring method consumes application/json and the error message says that what you're sending is not a valid JSON.
Following that line, I believe that your issue is a $.extend(addParam), when set with a single argument it will extend a jQuery namespace with the object, and won't return any JSON object to be stringified (and nothing being sent to the server). The possible solution is either removing the extend function, or adding another parameter in which case a valid JSON object will be returned, e.g.
function sendData() {
var addParam = createAddParam();
$.ajax({
url : "/GradleSpringMVC/inventory/add",
type : 'GET',
dataType : 'json',
data : JSON.stringify(addParam),
contentType : 'application/json',
mimeType : 'application/json'
}).done(function(data) {
// temGrid.addJSONData(data);
}).fail(function(error) {
// parseToPageAlerts(error.responseText);
}).always(function() {
// hideLoading()
});}
Found the answer. Just changed the version of jackson to 1.9.12
'org.codehaus.jackson:jackson-mapper-asl:1.9.12'

Categories

Resources