creating jquery custom object - javascript

In asp I have a function as:
public async Task<IHttpActionResult> updateComment(int id, Comment comment)
{
//some stuff
}
To send data to this function I have created an ojbect as (I am working with knockout.js):
var com = {
id: self.id,
description: self.description,
postedBy: self.postedById,
time: new Date($.now()),
adId: self.adId,
};
And in ajax request I am sending data as:
$.ajax({
url: '/api/Comment/updateComment',
dataType: "json",
contentType: "application/json",
cache: false,
type: 'POST',
data: { id: com.id, comment: com },
success: function (data) {
alert("done");
},
error: function () {
alert("error");
}
});
But request does not goes to above asp.net function. I got error in browser console window 404 (Not Found) . Error is because it is not receiving comment object as it was expecting. I changed ajax request method to get to see url and url is below.
Is there something wrong with my defined com function? Why its not working?
Update:
public async Task<IHttpActionResult> updateComment()
{
//some stuff
}
I changed the function as above and its working fine. So it is confirmed that is some problem with com object. Function is not receiving object as it was expecting.
Update 2:
Now I changed function parameters to:
public async Task<IHttpActionResult> updateComment(Comment comment)
{
//some stuff
}
and send data as:
data: ko.toJSON(com),
and its again working fine!

error code is 405:Method not allowed i guess this is something like, your ajax is type:"Post" request but your backend is expecting some GET requests.
Another suggestion is that you can send a stringified object with this:
data : '{ "id":"' + com.id + '", "comment":"' + com + '"}',

If you are using ajax post with two parameters class object and other type you need to create other obj like below:
Note: Make sure that all properties of com object are same like your Comment class.
var com = {
id: self.id,
description: self.description,
postedBy: self.postedById,
time: new Date($.now()),
adId: self.adId,
};
var obj = {};
obj.id = com.id;
obj.comment = com;
And pass data using JSON.Stringy(obj) like below:
data: JSON.stringify(obj),
I had tested the code it is working check below screen shot:

Related

Model vs List<Model> when sending post request to controller using Ajax

I have been trying to send a list model to controller using ajax but it seems it is not working at all
Model
public string MyModel {
public string myfieldName {get;set;}
}
controller
public JsonResult Create(List<myModel> list)
{
return Json("Success");
}
post request
$("body").on("click", "#btnSave", function () {
var list= new Array();
list = [{ myfieldName: 'ABC' }, { myfieldName: 'DEF' }];
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "/Project/Create",
data: JSON.stringify({ list }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
so when I send this through, I check the browser and I can see that the request payload is sent with json object list
However when I go to controller the list is not binding it at all, so I check the http.context to check the request payload there and it all empty.
on the other hand when I change the controller like below
sending request with only model
public JsonResult Create(myModel data)
{
return Json("Success");
}
and change the js with below
$("body").on("click", "#btnSave", function () {
var data ={};
data.myfieldName= "test";
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "/Project/Create",
data: data,
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
the only difference here is that I don't send as json, so my question what is the is the difference between sending model vs a list of model using ajax
and what can I change to get the controller to bind the data or accept a list of model data
noting i'm using .Net core 2.0
Thank you
I usually use this method to send my Model as a List to my Controller method. I will try to show you regarding your scenario, how you can do this:
AJAX:
$("body").on("click", "#btnSave", function () {
var list= new Array();
list = [{ myfieldName: 'ABC'}, { myfieldName: 'DEF'}];
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "#Url.Action("Create","Project")",
data:{"json": JSON.stringify(list)},
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
}
});
});
And you can receive your Model like this in your Create method:
Make sure to import the System.Web.Script.Serialization namespace:
using System.Web.Script.Serialization
[HttpPost]
public JsonResult Create(string json)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
List<string> myfieldName=new List<string>();
//Access your array now
foreach (var item in jsondata)
{
myfieldName.Add(item["myfieldName"]);
}
//Do something with the list here
return Json("Success");
}
Hope this helps you out.
Another method would be to utilize unobtrusive AJAX. All you would need is to install Microsoft jQuery unobtrusive AJAX from your Nuget Package Manager.
Then, in your view, call the following:
#{using (Ajax.BeginForm("Create", "ControllerName", null, new AjaxOptions()
{
HttpMethod = "POST",
// ...
}
}))
{
// Html code goes here
}
And also make sure that you include this at the bottom of your view:
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
Then, you can have a normal ActionResult setup (instead of JsonResult) for your controller and accept an argument of List list.

pass javascript response variable to spring controller function

The following javascript code works with the facebook login window appearing and allowing a user to login. The response values are captured and I know it works as alerts appear where setup but I cannot pass the value back to a controller method.
#RequestMapping(value ="/getAccessToken" , method = RequestMethod.POST)
public #ResponseBody String getAccessToken(#RequestBody String token){
System.out.println(token);
return token;
}
Javascript method called:
function doLogin() {
FB.login(function(response) {
alert(response);
console.log(response);
if (response.authResponse) {
alert(response.authResponse.userID);
alert(response.authResponse.accessToken);
var Token = response.authResponse.accessToken;
alert(Token);
$.ajax({
type: "POST",
url: "/HelloController/getAccessToken",
data: Token,
success: function (result) {
alert("Token");
},
error: function (result) {
alert("oops");
}
});
document.getElementById('loginBtn').style.
display = 'none';
getUserData();
}}, {perms:'manage_pages',
scope: 'email,public_profile', return_scopes: true});
};
The error I get is the following:
WARN 25660 --- [nio-8080-exec-9]
o.s.web.servlet.PageNotFound :
Request method 'POST' not supported
Appreciate responses.
The problem could be that you are using a new version of JQuery that sends request data as post form data instead of JSON as default. Try changing your ajax call to the following. The form data would not be recognized by your controller so if this is the case you should see a 404.
$.ajax({
type: "POST",
traditional: true,
url: "/HelloController/getAccessToken",
data: JSON.stringify(Token),
success: function (result) {
alert("Token");
},
error: function (result) {
alert("oops");
}
});
For reference see this post: Send JSON data via POST (ajax) and receive json response from Controller (MVC)

HttpClient PostAsync equivalent in JQuery with FormURLEncodedContent instead of JSON

I wrote a JQuery script to do a user login POST (tried to do what I have done with C# in the additional information section, see below).
After firing a POST with the JQuery code from my html page, I found the following problems:
1 - I debugged into the server side code, and I know that the POST is received by the server (in ValidateClientAuthentication() function, but not in GrantResourceOwnerCredentials() function).
2 - Also, on the server side, I could not find any sign of the username and password, that should have been posted with postdata. Whereas, with the user-side C# code, when I debugged into the server-side C# code, I could see those values in the context variable. I think, this is the whole source of problems.
3 - The JQuery code calls function getFail().
? - I would like to know, what is this JQuery code doing differently than the C# user side code below, and how do I fix it, so they do the same job?
(My guess: is that JSON.stringify and FormURLEncodedContent do something different)
JQuery/Javascript code:
function logIn() {
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
success: getSuccess,
error: getFail
});
} catch (e) {
alert('Error in logIn');
alert(e);
}
function getSuccess(data, textStatus, jqXHR) {
alert('getSuccess in logIn');
alert(data.Response);
};
function getFail(jqXHR, textStatus, errorThrown) {
alert('getFail in logIn');
alert(jqXHR.status); // prints 0
alert(textStatus); // prints error
alert(errorThrown); // prints empty
};
};
Server-side handling POST (C#):
public override async Task ValidateClientAuthentication(
OAuthValidateClientAuthenticationContext context)
{
// after this line, GrantResourceOwnerCredentials should be called, but it is not.
await Task.FromResult(context.Validated());
}
public override async Task GrantResourceOwnerCredentials(
OAuthGrantResourceOwnerCredentialsContext context)
{
var manager = context.OwinContext.GetUserManager<ApplicationUserManager>();
var user = await manager.FindAsync(context.UserName, context.Password);
if (user == null)
{
context.SetError(
"invalid_grant", "The user name or password is incorrect.");
context.Rejected();
return;
}
// Add claims associated with this user to the ClaimsIdentity object:
var identity = new ClaimsIdentity(context.Options.AuthenticationType);
foreach (var userClaim in user.Claims)
{
identity.AddClaim(new Claim(userClaim.ClaimType, userClaim.ClaimValue));
}
context.Validated(identity);
}
Additional information: In a C# client-side test application for my C# Owin web server, I have the following code to do the POST (works correctly):
User-side POST (C#):
//...
HttpResponseMessage response;
var pairs = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>( "grant_type", "password"),
new KeyValuePair<string, string>( "username", userName ),
new KeyValuePair<string, string> ( "password", password )
};
var content = new FormUrlEncodedContent(pairs);
using (var client = new HttpClient())
{
var tokenEndpoint = new Uri(new Uri(_hostUri), "Token"); //_hostUri = http://localhost:8080/Token
response = await client.PostAsync(tokenEndpoint, content);
}
//...
Unfortunately, dataType controls what jQuery expects the returned data to be, not what data is. To set the content type of the request data (data), you use contentType: "json" instead. (More in the documentation.)
var postdata = JSON.stringify(
{
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
});
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: postdata,
dataType: "json",
contentType: "json", // <=== Added
success: getSuccess,
error: getFail
});
If you weren't trying to send JSON, but instead wanted to send the usual URI-encoded form data, you wouldn't use JSON.stringify at all and would just give the object to jQuery's ajax directly; jQuery will then create the URI-encoded form.
try {
jQuery.ajax({
type: "POST",
url: "http://localhost:8080/Token",
cache: false,
data: {
"username": document.getElementById("username").value,
"password": document.getElementById("password").value
},
dataType: "json",
success: getSuccess,
error: getFail
});
// ...
To add to T.J.'s answer just a bit, another reason that sending JSON to the /token endpoint didn't work is simply that it does not support JSON.
Even if you set $.ajax's contentType option to application/json, like you would to send JSON data to MVC or Web API, /token won't accept that payload. It only supports form URLencoded pairs (e.g. username=dave&password=hunter2). $.ajax does that encoding for you automatically if you pass an object to its data option, like your postdata variable if it hadn't been JSON stringified.
Also, you must remember to include the grant_type=password parameter along with your request (as your PostAsync() code does). The /token endpoint will respond with an "invalid grant type" error otherwise, even if the username and password are actually correct.
You should use jquery's $.param to urlencode the data when sending the form data . AngularJs' $http method currently does not do this.
Like
var loginData = {
grant_type: 'password',
username: $scope.loginForm.email,
password: $scope.loginForm.password
};
$auth.submitLogin($.param(loginData))
.then(function (resp) {
alert("Login Success"); // handle success response
})
.catch(function (resp) {
alert("Login Failed"); // handle error response
});
Since angularjs 1.4 this is pretty trivial with the $httpParamSerializerJQLike:
.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
method: 'POST',
url: baseUrl,
data: $httpParamSerializerJQLike({
"user":{
"email":"wahxxx#gmail.com",
"password":"123456"
}
}),
headers:
'Content-Type': 'application/x-www-form-urlencoded'
})
})

get the parmeter from ajax to node.js to mongoDB

i have this problem when i try to do some test by clicking a button which call a JavaScript function that does an ajax call and pass a parameter to my node.js server(express) which save it to my mongoDB.
the problem is that all the time i see the value in the DB as null, after researching i found that the problem is how to get the parameter "name" and read it on the node.js side
i try req.body.name or req.query.name but stil nothing..
hope you can help me,
maybe its in my code or syntax problem, wait for your help
java script code :
function savePre()
{
var parameters = { name: 'test' };
$.ajax({
url: '/savePre',
type: 'POST',
data: JSON.stringify(parameters),
success: function () {},
dataType: 'json'
});
}
node.js code (in the index.js code) :
exports.savePre = function(db) {
return function(req, res) {
// Get our form values. These rely on the "name" attributes
var json = req.query.name;
// Set our collection
var collection = db.get('PresentationCollection');
// Submit to the DB
collection.insert({
"JsonToSave": json
}, function (err, doc) {
if (err) {
// If it failed, return error
res.send("There was a problem adding the information to the database.");
}
});
}
}
Your client side code can be improved without JSON.stringify:
$.ajax({
url: '/savePre',
type: 'POST',
data: parameters,
success: function () {}
});

JSON pass null value to MVC 4 controller in IE9

I got some problem while posting JSON data into MVC 4 controller.
Below method is working fine in Firefox but unfortunately failed in IE 9
The JavaScript :
var newCustomer = {
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.ajax({
url: '#Url.Content("~/CustomerHeader/CreateCustomerHeader")',
cache: false,
type: "POST",
dataType: "json",
contentType: 'application/json; charset=utf-8',
data: JSON.stringify(newCustomer),
success: function (mydata) {
$("#message").html("Success");
},
error: function () {
$("#message").html("Save failed");
}
});
and this is my controller :
public JsonResult CreateCustomerHeader(CustomerHeader record)
{
try
{
if (!ModelState.IsValid)
{
return Json(new { Result = "ERROR", Message = "Form is not valid! Please correct it and try again." });
}
RepositoryHeader.Update(record);
return Json(new { Result = "OK", Record = record});
}
catch (Exception ex)
{
return Json(new { Result = "ERROR", Message = ex.Message });
}
}
the "data" variable as in public JsonResult CreateCustomerHeader(CustomerHeader **data**) is getting NULL but while using FireFox it holds the correct value.
UPDATE : New method trying using $.post
function CreateNewCustomer(newCustomer) {
$.post("/CustomerHeader/CreateCustomerHeader",
newCustomer,
function (response, status, jqxhr) {
console.log(response.toString())
});
}
Based off the bit that you've shown, this is a simplified variation that may work more consistently, using jQuery.post() (http://api.jquery.com/jQuery.post/):
var data = {
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.post({
'#Url.Action("CreateCustomerHeader", "CustomerHeader")',
data,
function(response, status, jqxhr){
// do something with the response data
}).success(function () {
$("#message").html("Success");
}).error(function () {
$("#message").html("Save failed");
});
$.post() uses $.ajax as it's base, but abstracts some of the details away. For instance, $.post calls are not cached, so you don't need to set the cache state (and setting it is ignored if you do). Using a simple JavaScript object lets jQuery decide how to serialize the POST variables; when using this format, I rarely have issues with the model binder not being able to properly bind to my .NET classes.
response is whatever you send back from the controller; in your case, a JSON object. status is a simple text value like success or error, and jqxhr is a jQuery XMLHttpRequest object, which you could use to get some more information about the request, but I rarely find a need for it.
first of all I would like to apologize #Tieson.T for not providing details on JavaScript section of the view. The problem is actually caused by $('#addCustomerHeaderModal').modal('hide') that occurred just after ajax call.
The full script :
try{ ..
var newCustomer =
{
CustName: $("#CustName").val(),
CustLocalName: $("#CustLocalName").val(),
CustNumber: $("#CustNumber").val(),
CountryID: $("#SelectCountry").val(),
City: $("#City").val()
};
$.ajax({
url: '/CustomerHeader/CreateCustomerHeader',
cache: false,
type: "POST",
dataType: "json",
data: JSON.stringify(newCustomer),
contentType: "application/json; charset=utf-8",
success: function (mydata) {
$("#message").html("Success");
},
error: function () {
$("#message").html("Save failed");
}
});
}
catch(Error) {
console.log(Error.toString());
}
//$('#addCustomerHeaderModal').modal('hide')//THIS is the part that causing controller cannot retrieve the data but happened only with IE!
I have commented $('#addCustomerHeaderModal').modal('hide') and now the value received by controller is no more NULL with IE. Don't know why modal-hide event behave like this with IE9.
Thanks for all the efforts in solving my problem guys :-)

Categories