I'm reaaallly new at JSON, but here's what I got. I needed to create an object that contains an array/list and a couple flat fields. For example:
var names= new Array();
names[0] = "Christy";
names[1] = "Jeremy";
var obj = {
names: names,
age: "21+",
comment: "friends"
};
I then stringify it and attempt to send it to a pagemethod via AJAX:
var jsonData = JSON.stringify(obj);
sendData(obj);
And then the send:
function sendData(jsonData) {
$.ajax({
type: "POST",
url: "Default.aspx/TestArray",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert('win');
},
error: function (a, b, ex) {
alert('fail');
}
});
}
so all together:
$(document).ready(function () {
$("#btnSubmit").click(function (e) {
e.preventDefault();
var names = new Array();
names[0] = "Christy";
names[1] = "Jeremy";
var obj = {
names: names,
age: "21+",
comment: "friends"
};
var jsonData = JSON.stringify(obj);
sendData(jsonData);
});
function sendData(jsonData) {
$.ajax({
type: "POST",
url: "Default.aspx/TestArray",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
alert(msg.d);
},
error: function (a, b, ex) {
alert("oops: " + ex);
}
});
}
});
I'm not sure if I'm doing this right. It doesn't even get to the webmethod, rather it goes straight to the error function. But just for the sake of conversation, this is what I have in the codebehind:
[WebMethod()]
public static string TestArray(string guids)
{
Comment cmt = (Comment)JsonConvert.DeserializeObject(guids, typeof(Comment));
return "Winner";
}
And of course class im trying to deserialize into:
public class Comment
{
public List<string> names { get; set; }
public string age { get; set; }
public string comment { get; set; }
}
According to the signature of your web method:
public static string TestArray(string guids)
you must send a single string argument whereas you are sending an entire complex JSON object which doesn't match. So:
var jsonData = JSON.stringify({ guids: 'foo bar' });
Now if you wanted to send a complex structure use:
public static string TestArray(Comment comment)
and then:
var names = new Array();
names[0] = "Christy";
names[1] = "Jeremy";
var obj = {
names: names,
age: "21+",
comment: "friends"
};
var jsonData = JSON.stringify({ comment: obj });
Also inside your web method don't do any JSON serialization/deserializations. That's infrastructure stuff that's handled for you by the framework. So to recap:
[WebMethod]
public static string TestArray(Comment comment)
{
return "Winner";
}
and then:
var names = new Array();
names[0] = "Christy";
names[1] = "Jeremy";
var obj = {
names: names,
age: "21+",
comment: "friends"
};
var jsonData = JSON.stringify({ comment: obj });
$.ajax({
type: "POST",
url: "Default.aspx/TestArray",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
// Notice the .d property. That's ASP.NET PageMethods
// serialize the response.
alert(msg.d);
},
error: function (a, b, ex) {
alert('fail');
}
});
Also in order to be able to easily debug such problems in the future I would very strongly recommend you using a javascript debugging tool such as FireBug which shows you any potential js errors that you might have as well as all network traffic including AJAX requests.
You're json data object does not have to be Stringified. JQuery automatically creates a json object for it:
var jsonData = JSON.stringify(obj);
sendData(jsonData);
Can become:
sendData(obj);
Also, in code behind you use JsonConvert from the JSON.Net library, .NET also has a (somewhat limited) JSON parser called JavaScriptSerializer. That way you can use something like:
public static string TestArray(string guids)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
// Deserialize
Comment cmt = serializer.Deserialize<Comment>(guids);
}
Related
I have JavaScript function where I have an array and when I send that array to my C# controller, it should be in such way way that my controller should understand.
JavaScript function
function Check(obj) {
var eArray = $('..').map(function () {
return this.getAttribute("value");
}).get();
$.ajax({
url: "/Order/Check",
data: { GUID: JSON.stringify(eArray) },
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
});
My Controller
public ActionResult Check()
{
string guid = HttpContext.Request["GUID"];
var result = //send the result
return Json(result, JsonRequestBehavior.AllowGet);
}
I would like to get an array in my controller.
I'm not really sure what you are trying to achieve. From what I saw in your comments, you are sending an array of GUIDs to your controller, but that results in it being send as a string, and you want an array.
I tested your code and modified it a bit:
$.ajax({
type: "POST",
url: /your url/,
contentType: "application/json; charset=utf-8",
dataType: "json",
cache: false,
data: JSON.stringify({GUID: eArray}),
});
Where eArray is let eArray = ['D5FAF478-CF43-40E1-BE79-BB90147A3194', '2E79B23E-D264-4901-A065-7E0B7032A5D8']
Then, in my controller, I receive it as a model:
public class Dto
{
public string[] GUID { get; set; }
}
Then, you can use it like this:
[HttpPost]
public IActionResult Post([FromBody] Dto dto)
{
var listOfGuids = dto.GUID.Select(guid => Guid.Parse(guid)).ToList();
var result = Services.CheckRecords(listOfGuids);
...
}
It seems that unfortunately the standard JavaScriptSerializer.Deserialize doesn't handle Guid type.
Therefore, I would go with something like
public ActionResult Check()
{
string guidsStr = HttpContext.Request["GUID"];
var guids = new List<Guid>();
foreach (var guid in Regex.Replace(guidsStr, "[\\[\\\"\\]]", "").Split(",")) {
Guid newGuid;
if (Guid.TryParse(guid, out newGuid)) {
guids.Add(newGuid);
} else {
// handle invalid guide value
}
}
// guids list now contains parsed Guid objects
// do here what you need to do with the list of guids
return Json(result, JsonRequestBehavior.AllowGet);
}
Please let me know if this helps.
In my web service (order.asmx) I have a method which accept a viewmodel as a parameter. Method signature is below.
public string CreateOrder(OrderModel order)
and my order.cs is like below,
public class OrderModel: BaseClass
{
public OrderModel()
{
this.RestaurantIDs = new List<long>();
}
public long OrderID { get; set; }
public List<long> RestaurantIDs { get; set; }
}
I'm passing all the order related details using ajax call to this service method. To pass the RestaurantIDs I'm using an array which gives me 500 server error. I tried with stringify as well but didnt work. Anyone can help me with this?
ajax call
function createOrderObject()
{
var order = new object;
order.CustomerName = $("#txtName").val();
order.RestaurantIDs = selectedRestaurants.map(function (obj) {
return obj.RestaurantID;
});
}
// here the selectedRestaurants is object array.
function createOrder()
{
var order = createOrderObject();
var url = '/Service/OrderService.asmx/CreateOrder';
var dataSet = '{orderModel:' + JSON.stringify(order) + '}';
var orderInfo = $.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: url,
data: dataSet,
dataType: "json",
error: function () {
giveNotification({ NotificationCode: 500, Message: "Internal Server Error, Please try again." });
loadingImg(ele, "hide");
});
}
the error message }
The JSON Object always return undefined in spite of the object contains data, i check it by using breakpoints in debugging
This is Action method in Controller:
public JsonResult GetMoreComments(int CommsCount, int ArticleID)
{
List<ComViewModel> comms = articleService.GetMoreComments(ArticleID, CommsCount);
return Json( comms );
}
and I also replaced the code in Action method to simple code like that but not work too:
public JsonResult GetMoreComments(int CommsCount, int ArticleID)
{
ComViewModel com = new ComViewModel
{
CommentContent = "cooooooooooontent",
CommentID = 99,
SpamCount = 22
};
return Json( com );
}
This is jQuery code for AJAX:
function GetMoreComments() {
$.ajax({
type: 'GET',
data: { CommsCount: #Model.Comments.Count, ArticleID: #Model.ArticleID },
url: '#Url.Action("GetMoreComments", "Comment")',
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
var JsonParseData = JSON.parse(result);
alert(JsonParseData[0].CommentID)
alert(result[0].CommentID);
alert(result[0]["CommentID"]);
}
});
}
Usually you would have to parse your data if you need to alert it the way you have it. alert(result) should show data. If you need to access array of objects you must parse it first. Here is my example....
jQuery.post(ajaxurl, data, function(response) {
alert('Got this from the server: ' + response);
//PARSE data if you need to access objects
var resultstring = response.replace(',]',']');
var JsonParseData = JSON.parse(resultstring);
alert(JsonParseData[0].address)
});
That is wordpress ajax but its the same concept
I have asp.net application where need to implement autocomplete, I try to load list of names from server side and then deserealize it in js code, but have an 500 error, can anybody help me?
Unknown web method GetListofCompanies.
Parameter name: methodName
Code:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string GetListofCompanies(string name) {
var companies = _companyRepo.GetAll().Select(x => x.Name).ToList();
// Create a JSON object to create the response in the format needed.
JavaScriptSerializer oJss = new JavaScriptSerializer();
// Create the JSON response.
String strResponse = oJss.Serialize(companies);
return strResponse;
}
JS:
var name = "";
$.ajax({
url: "Company.aspx/GetListofCompanies",
type: "post",
data: { name: name },
dataType: "json",
contentType: 'application/json',
success: function (data) {
// Get the data.
var responseArray = JSON.parse(data.d);
$("#txtName").autocomplete({
source: responseArray
});
}
});
// Namespaces.
using System.Web.Services;
using System.Web.Script.Serialization;
[WebMethod]
public static string GetListofCompanies(string name)
{
List<string> companies = new List<string>();
companies.Add("Company1");
companies.Add("Company2");
companies.Add("Company3");
companies.Add("Company4");
companies.Add("Company5");
// Create a JSON object to create the response in the format needed.
JavaScriptSerializer oJss = new JavaScriptSerializer();
// Create the JSON response.
String strResponse = oJss.Serialize(companies);
return strResponse;
}
// JS
function request() {
var name = "";
var data = { name: name };
$.ajax({
url: "Default.aspx/GetListofCompanies",
type: "POST",
contentType: 'application/json',
data: JSON.stringify(data)
}).success(function (data) {
// do your stuff here
})
.fail(function (e) {
alert("Error");
});
}
I have been working with Web API and found an interesting observation that I am not able to understand.
controller:
public class UserController: ApiController
{
public void Post(MyViewModel data)
{
//data is null here if pass in FormData but available if its sent through Request Payload
}
}
viewModel
public class MyViewModel{
public long SenderId { get; set; }
public string MessageText { get; set; }
public long[] Receivers { get; set; }
}
JS that is not working
var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");
$.ajax(
{
url: '/api/User',
type: 'POST',
data: JSON.stringify(usr),
success: function(response) { debugger; },
error: function(error) {debugger;}
});
JS that is working
var usr = {};
usr.SenderId = "10";
usr.MessageText = "test message";
usr.Receivers = new Array();
usr.Receivers.push("4");
usr.Receivers.push("5");
usr.Receivers.push("6");
$.post( "/api/User", usr)
.done(function( data ) {
debugger;
});
So, if I pass on $.ajax with lots of other configuration like type, contentType, accept etc, it still don't bind model correctly but in case of $.post it works.
Can anybody explain WHY?
Try looking at what gets POSTed when you try it with $.ajax (e.g. with Fiddler of F12 tools of your choice). It can very well be that jQuery passes the data as URL-encoded string rather that as JSON literal.
To fix the issue try specifying dataType together with contentType parameter. Also, I don't think you need JSON.stringify, just pass the JSON literal you're creating:
$.ajax({
data: usr,
dataType: 'json',
contentType: 'application/json',
/* The rest of your configuration. */
});
Here's the TypeScript method that we use in one of our projects (ko.toJSON returns a string representing a JSON literal passed as a method parameter):
public static callApi(url: string, type?: string, data?: any): RSVP.Promise {
return new RSVP.Promise((resolve, reject) => {
$.ajax('/api/' + url, {
type: type || 'get',
data: data != null ? ko.toJSON(data) : null,
dataType: 'json',
contentType: 'application/json; charset=utf-8',
success: () => {
resolve.apply(this, arguments);
},
error: () => {
reject.apply(this, arguments);
}
});
});
}
Hope this helps.