string[] via Ajax and ASP.Net (MVC) - javascript

my problem is following.
I try to parse some data via ajax, passing the data to my controller:
AJAX
$.ajax({
type: "GET",
url: "ParseOrganizaitonPath",
data: {
organizationPath: $('#organizationPath').val()
},
success:
function (data) {
//data is from type string with value "System.string[]"
//but should be from type System.string[]
});
}
});
Controller
public string[] ParseOrganizaitonPath(string organizationPath)
{
List<string> organizations = organizationPath.Split('/').ToList();
return organizations.ToArray();
}
I am reaching the controller method and in it everything is fine, but the data that is comming back (ajax part, success method) is just a string ("System.string[]", data[0] S, data[1]y data[2]s...) but not the data I want. (For example if i pass the input "test/one" I want to have as result data[0] test, data[1] one)
Hope you understand what my Problem is.
Thanks in advance!
Julian

Have to tried to use the JavaScriptSerializer? Have a look at this example:
public string ParseOrganizaitonPath(string organizationPath)
{
List<string> organizations = organizationPath.Split('/').ToList();
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
return oSerializer.Serialize(organizations);
}
To deserialize the JSON string with JavaScript you can use the parse function:
var array = JSON.parse(data);

I found a way where you don't have to serialize it (on c# site) and parse it (on javascript site)
Just use the JSON Method that is inherited from the Controller and return an JsonResult:
public JsonResult ParseOrganizaitonPath(string organizationPath)
{
List<string> organizations = organizationPath.Split('/').ToList();
return JSON(organizations);
}
On the client site (javascript) you have to use JSON.stringfy(dataObject) for data that you want to send to your controller-method.
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
url: "ParseOrganizaitonPath",
data: JSON.stringify(myDataObject),
success:
function (data) {
//use your data
});
}
});
That's how it worked for me.
Good luck!
Julian

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.

Ajax javascript Map to Spring controller

I am trying ajax Javascript Map, to spring controller. but it's getting null in backend. Please excuse if i am repeating question.
I can't change Map type, as my whole front end logic on it. Because set, get and has method from Map is what I need.
var ansMap = new Map(); // This way i created object
// added many values in ansMap,
$.ajax({
type: "POST",
url: myUrl,
contentType : 'application/json',
//cache: false,
dataType : 'json',
data : ansMap, // can't JSON.stringy(ansMap) as it gives empty json
success: function(result) {
console.log(result);
},
Spring code
#RequestMapping (value="myUrl", method=RequestMethod.POST)
public #ResponseBody String saveData(#RequestParam(required = false, value = "mapData") Map<String,List<String>> mapData, Model map)
{
log.info("Call Success");
log.info("mapData: "+mapData);
Please suggest what needs to be done here.
You can actually send your Map without mutating the value
var ansMap = new Map(); // This way i created object
// added many values in ansMap,
$.ajax({
type: "POST",
url: myUrl,
contentType : 'application/json',
//cache: false,
dataType : 'json',
data : JSON.stringify(Object.fromEntries(ansMap)), // can't JSON.stringy(ansMap) as it gives empty json
success: function(result) {
console.log(result);
},
That will turn it into a javascript object.
Object.fromEntries Will turn you Map into a javascript object, without altering the original Map
Regarding your backend i think you mis-interpret the #RequestParam annotation
The #RequestParam is to extract query parameters, form parameters and even files from the request.
I think that what you are looking for is #RequestBody.
Meaning you would be looking for something similar to :
#RequestMapping(value="/myUrl",method = RequestMethod.POST)
public String saveData( #RequestBody Map<String,Object> body) {
This should work
page
<button id="doPost"> post </button>
<script>
$(function () {
var map = new Map();
map.set('CIQ_2','aa');
map.set('CIQ_3','78965412300');
console.log(map);
$("#doPost").click (function() {
var settings = {
beforeSend: function(xhr, options) {
xhr.setRequestHeader("content-type" ,"application/json; charset=utf-8");
},
type: 'POST',
url: '/post' ,
data: JSON.stringify(Object.fromEntries(map))
}
$.ajax(settings).done(function(result) {
console.log("done : " + result);
});
});
});
</script>
Controller
#PostMapping("/post")
#ResponseBody
public String post(#RequestBody Map<String,String> data) {
System.out.println(data);
return "data well received";
}
will print
{CIQ_2=aa, CIQ_3=78965412300}
working code on GitHub

MVC5 Controller not receiving JSON Object

I have a controller with method as follows:
public JsonResult Save(List<BlogInfo> list)
{
return Json(new { Data = "" }, JsonRequestBehavior.AllowGet);
}
And I have an ajax post from the client as follows:
$.ajax({
url: "Home/Save",
type: "post",
contentType: "application/json",
data: ko.mapping.toJSON(ViewModel),
success: function (response) {
alert(response.Status);
}
});
My problem is that list parameter to the controller is always null. I tried changing it to string instead of List but that is also null.
Using Fiddler, I can see that the JSON is being pass as follows:
{"Data":[{"Id":1,"Title":"Sudoku Solver","Description":"Programmed Sudoku Solver","Tags":["programming","sudoku"]},{"Id":2,"Title":"Picnic","Description":"Went to millpoint","Tags":["picnic"]},{"Id":0,"Title":"Title","Description":"Description","Tags":[]}]}
The JSON you have shown doesn't represent an array, so you cannot possibly expect to bind it to a list on the server. To achieve that make sure that you are sending an array of objects from the client:
data: ko.mapping.toJSON(ViewModel.Data);
Here we take the ViewModel.Data property which represents an array so that we send only the desired JSON:
[{"Id":1,"Title":"Sudoku Solver","Description":"Programmed Sudoku Solver","Tags":["programming","sudoku"]},{"Id":2,"Title":"Picnic","Description":‌​"Went to millpoint","Tags":["picnic"]},{"Id":0,"Title":"Title","Description":"Description‌​","Tags":[]}]

Bad Request Errors when trying to Post large JSON data

First of all, I'm a new developer, so I apologize in advance if I'm missing something obvious.
I'm developing a web application to work offline with large amounts of data in an IndexedDB. When the user goes to the webapp, the client grabs the entire database from the server and stores it for use in the indexeddb. That works fine, but when I'm trying to use a post method to send the data (again multiple records) back to WCF, I get method not allowed or bad request when trying to send an ajax body parameter, and when I do use uri parameters, it hits the server, but not all the data is sent. I thought perhaps invalid characters may be a factor so I used the encodeURIComponent method in javascript to convert invalid characters to be valid in a uri parameter. I've also tried compressing the data with a javascript compression api called LZString. I've tried using XMLHttpRequest(which I don't fully understand). This webapp has to work offline so I can't make a server call except for initially getting data when the client first opens and for syncing data back to the server, which is why I have to send large amounts of data at a time.
I'm also using an IndexedDB wrapper called Dexie.js.
Samples of my code is below. Some code is commented, but is left to show what I've tried.
This is what I have on the server..
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "REST_SendCompletedServiceOrders",
BodyStyle = WebMessageBodyStyle.Wrapped)]
[FaultContract(typeof (Exception))]
bool REST_SendCompletedServiceOrders(string compressedWebData);
This is the click event on the client used to sync back..
$('#syncCompletedData').on('click', function() {
db.ServiceOrder
.toArray(function(so) {
var completedServiceOrders = [];
for (var i = 0; i < so.length; i++) {
if (so[i].IsCompleted) {
completedServiceOrders.push(so[i]);
};
}
var customerId = sessionStorage.getItem("customerId");
var companyId = sessionStorage.getItem("companyId");
var computerId = sessionStorage.getItem("computerId");
var webData = JSON.stringify({ webCustomerId: customerId, webCompanyId: companyId, webComputerId: computerId, webServiceOrder: completedServiceOrders });
alert(webData);
alert("before compression is " + webData.length);
var URIEncodedWebData = encodeURIComponent(webData);
var JSONWebData = JSON.stringify(URIEncodedWebData);
var compressedWebData = LZString.compressToUTF16(JSONWebData);
alert("after compression is " + compressedWebData.length);
debugger;
try {
$.ajax({
type: "POST",
url: "MFSRemoteDataService/REST_SendCompletedServiceOrders",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: { compressedWebData: compressedWebData },
success: function(data) { alert(JSON.stringify(data)); },
failure: function(errMsg) {
alert(errMsg);
}
});
} catch (e) {
alert(e);
}
});
});
Before compression data length is 7707.
After compression data length is 1831.
Thanks in advance for any help, feedback, criticism, etc..
In the shown snippet, you are composing the ajax data for use in a get, which usually means you prepare a uri. However, since he is both using post and ajax, the information will be sent in the post request body and as such does not need to be encoded.
The encoding is bloating the stringified json. You can stop at webdata and post that all by itself, remove the dataType parameter in the ajax options, switch to using traditional:true in the ajax options, and it should all properly model bind.
It is hard to tell what your server side view model looks like, but if the accepting parameter is named compressedWebData (names must be exact, same goes with structure), then it would probably work like this
//code as shown in OP
//replace var webData = with the following
var compressedWebData = { webCustomerId: customerId, webCompanyId: companyId, webComputerId: computerId, webServiceOrder: completedServiceOrders };
try {
$.ajax({
type: "POST",
url: "MFSRemoteDataService/REST_SendCompletedServiceOrders",
contentType: "application/json",
data: JSON.stringify(compressedWebData),
traditional:true,
success: function(data) { alert(JSON.stringify(data)); },
failure: function(errMsg) {
alert(errMsg);
}
});
} catch (e) {
alert(e);
}
I figured out my problem. I've been trying to pass a string to the contract method, and I kept getting bad request errors. Instead, I wrapped the Json string and sent it to an object instead of a string that I created on the server.
I wrapped the JSON and sent it in the body of the ajax request..
var rawWebData = {
WebCustomerID: customerId,
WebCompanyID: companyId,
WebComputerID: computerId,
WebServiceOrders: completedServiceOrders
};
var rawData = { webData: rawWebData };
var webData = JSON.stringify(rawData);
try {
$.ajax({
type: "POST",
url: "MFSRemoteDataService/REST_SendCompletedServiceOrders",
contentType: "application/json; charset=utf-8",
dataType: "json",
traditional: true,
data: webData,
success: function (data) {
alert(JSON.stringify(data));
},
failure: function (errMsg) {
alert(errMsg);
}
});
} catch (e) {
alert(e);
}
});
Then I created a class to collect the data...
[DataContract]
public class WebServiceOrder
{
[DataMember]
public Int32 WebCustomerID { get; set; }
[DataMember]
public Int32 WebCompanyID { get; set; }
[DataMember]
public Int32 WebComputerID { get; set; }
[DataMember]
public virtual List<ServiceOrder> WebServiceOrders { get; set; }
}
Then I changed the contract method to accept the object I created instead of a string. WCF deserialized the JSON string.
[OperationContract]
[WebInvoke(Method = "POST",
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "REST_SendCompletedServiceOrders",
BodyStyle = WebMessageBodyStyle.WrappedRequest)]
[FaultContract(typeof (Exception))]
bool REST_SendCompletedServiceOrders(WebServiceOrder webData);

Ajax data not getting to controller? why?

I am working with mvc4 application. I developed a form using .cshtml file, which inherits the model and has its corresponding controller action.
I am submitting the form using a ajax jquery like,
var body=$('#formId').serialize();
$.ajax({
url: submitAction,
type: "POST",
datatype: "json",
data: body,
success: function (data) {
if (data != null) {
alert("success");
}
});
"body" is fine and it has serialized data and the submitAction is the var which holds my controller action and the controll is transfered there.
EDIT:
My controller looks like,
public JsonResult(ParentModel model) /*here model always hold null values, WHY??*/
{
//stmts..
return Json(new {success=true}, JsonRequestBehaviour.AllowGet);
}
But, there the parameter of my controller action is showing null values. Can someone tell what could be the mistake and how can I resolve it?
$.ajax({
url: submitAction,
type: "POST", <-- you make post, but asp.net mvc controller receives default GET request
data: { model: body},
[HttpPost]
public JsonResult(string model) //<--now you pass string and to Deserialize in ParentModel
{
JavaScriptSerializer jss= new JavaScriptSerializer();
ParentModel pmodel = jss.Deserialize<ParentModel >(model);
return Json(new {success=true}, JsonRequestBehaviour.AllowGet);
}
Try edit data: section in you request,
remove datatype: "json"
And edit type model parameter to string

Categories