sending multiple models via json in mvc3 - json

Could not find exact matches for the question (some similar posts found) ..
How can multiple models be send via JSON to MVC3 controller e.g having the following parameters:
public JsonResult Add(Project pr, List<Modules> mod)
{
}
following technique was tried but did not work
function AddModules() {
var pname = $("#ProjectName").val();
var data = new Array();
var modules = new Array();
$("#ModuleTable tr").each(function () {
var row =
{
"ModuleName": $(this).find(".moduleName").val(),
"ModuleDesc": $(this).find(".moduleDesc").val(),
"ModuleSize": $(this).find(".moduleSize").val(),
"StartDate": $(this).find(".startDate").val(),
"ModuleId": "",
"ProjectName": pname
}
modules.push(row);
});
var project =
{
"ProjectName": $("#ProjectName").val(),
"ProjectDescription" : $("#ProjectDescription").val(),
"StartDate" : $("#ProjectStartDate").val(),
"ModuleName" : modules
}
data.push(project);
$.ajax({
url: "AddProject",
data: JSON.stringify(data),
type: "post",
contentType: "application/json; charset = utf-8",
dataType: "json",
success: function (status) {
alert(status);
}
});
}
The project class also contains a List type of Module class.

You are sending a string of JSON back to the server, so you have a type difference. Try something like this instead:
Client Side
var myFunction = function(){
var projectName = $("#ProjectName").val();
var projectDescription = $("#ProjectDescription").val();
$.post("[URL TO YOUR CONTROLLER]",{pName : projectName, pDescription: projectDescription},function(response){
alert(response);
});
};
Server Side
public ActionResult MyActionResult(FormCollection fc)
{
var projectName = fc["pName"];
var projectDescription = fc["pDescription"];
var result = projectName + " hase been posted!";
return Content(result);
}
Good luck!

Related

How to Serialize Model in View and Pass to Controller Action

I have a very specific need to serialize a model in the view and then pass it to a controller action at some point. I can get it to work by doing several hacks but its not pretty.
My test controller action
public ActionResult Index()
{
DefaultOptionValueRound defaultOptionValueRound = new DefaultOptionValueRound()
{
OptionId = 1835,
OptionValueId = 40343
};
TestModel testModel = new TestModel()
{
DefaultOptionValueRound = defaultOptionValueRound
};
return View(testModel);
}
The View
#using Common.Repository.Extensions
#model EngA.SandboxApplication.Controllers.TestModel
#Html.Hidden("DefaultOptionValueRound", Html.Raw(Json.Encode(Model.DefaultOptionValueRound)))
<input type="button" value="submit" onclick="SerializeModelTest.processOptionMag()"/>
<script language="javascript">
SerializeModelTest = {
processOptionMag: function () {
//Testing: This Works
//var defaultOptionValueRound = { OptionId: 1834, OptionValueId: 4034377 }
//var data = JSON.stringify({ defaultOptionValueRound: defaultOptionValueRound });
//This Does Not Work
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = { defaultOptionValueRound: defaultOptionValueRound }; //Stringify Does not work either
$.ajax({
contentType: 'application/json; charset=utf-8',
type: "Post",
cache: false,
url: '#Url.Action("ProcessOptionMag", "SerializeModelTest")',
data: data,
dataType: "json",
traditional: true,
success: function(data) {
alert(data);
}
});
}
}
</script>
The problem is that the serialized model is returned in a stringify form already.
There must be an elegant way of doing this without me have to do JS string manipulation to make it work.
Thank you for your help
I found out that I can un-stringify my result using JSON.Parse and then repackage it with other parameters for sending to the controller.
var defaultOptionValueRound = $("#DefaultOptionValueRound").val();
var data = JSON.stringify({ defaultOptionValueRound: JSON.parse(defaultOptionValueRound) });
Now everything works.

Tableau: import JSON data from simple REST call

I have a REST API (served by an external server) replying JSON formatted data.
From what I read from Tableau doc, there's available:
- WebDataConnector but you have to add a JS overload on your webpages, not very suitable for REST APIs
- importing JSON data from file, but doesn't answer my issue
Isn't there a simple way to integrate JSON data requested via REST call ?
You can use WDC, you are wrong that its not suitable for REST API. So you basically need to create 2 functions for getting fields and data for your datasets from API:
myConnector.getSchema = function (schemaCallback) {
$.ajax({
url: apiurl + JSON.parse(tableau.connectionData)['diggerID'] + "/sessions/last/data/one",
type: "GET",
headers: {
'Authorization': 'Token ' + JSON.parse(tableau.connectionData)['apiKey']
},
success: function(response){
var flatten = objectFlatten(response)
var columns = []
for (var key in flatten) {
var id = key.replace(/[^A-Za-z0-9_]+/g, '')
columns.push({
id: id,
alias: key,
dataType: tableauType(flatten[key])
})
}
var table = {
id: "digger_" + JSON.parse(tableau.connectionData)['diggerID'],
alias: tableau.connectionName,
columns: columns
}
schemaCallback([table]);
},
error: function (xhr, ajaxOptions, thrownError) {
tableau.abortWithError("Unable to get data. Make sure you used proper API key and you have at least one session for selected digger with dataset.");
}
});
};
myConnector.getData = function (table, doneCallback) {
$.ajax({
url: apiurl + JSON.parse(tableau.connectionData)['diggerID'] + "/sessions/last/data",
type: "GET",
headers: {
'Authorization': 'Token ' + JSON.parse(tableau.connectionData)['apiKey']
},
success: function(response){
var data = []
for (var i=0; i < response.length; i++) {
var flatten = objectFlatten(response[i])
var rec = {}
for (var key in flatten) {
var id = key.replace(/[^A-Za-z0-9_]+/g, '')
rec[id] = flatten[key]
}
data.push(rec)
}
table.appendRows(data);
doneCallback();
},
error: function (xhr, ajaxOptions, thrownError) {
tableau.abortWithError("Unable to get data. Make sure you used proper API key and you have at least one session for selected digger with dataset.");
}
});
};
For complete code you can check out for source code on github: https://github.com/Diggernaut/diggernaut-wdc

Spring MVC + Ajax error 400

I have a simple java application on Spring MVC and I send ajax request to Spring controller. When I set headers "Accept", "application/json" and "Content-Type", "application/json;charset=utf-8" in AJAX call I get error 400 in dubugger, when I delete it I get error 415.
If I change controller method signature to public String logoutPage (#RequestBody String obyavleniye) I get JSON string. What problem can be with parse request in controller?
JS method:
$("#advertForm").submit(function(e) {
e.preventDefault();
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
var obyavleniye = {
title: "Title",
price: "80",
description: "desc",
date: "2016-11-07 18:30:21",
authorid: "2",
category: "A",
state: "new",
img1: "http",
img2: "http",
img3: "http",
img4: "http",
};
var post_data = JSON.stringify(obyavleniye);
console.log(post_data);
$.ajax({
url : "/upload",
type: "POST",
dataType: 'json',
data: post_data,
beforeSend: function(xhr) {
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("Content-Type", "application/json;charset=utf-8");
xhr.setRequestHeader(header, token);
},
complete: function() {
console.log("Sent");
},
success: function (response) {
console.log("success");
console.log("response" + response);
},
error: function (data) {
console.log("error");
console.log(data);
}
});
});
Controller method:
#ResponseBody
#RequestMapping(value="/upload", method = RequestMethod.POST)
public String logoutPage (#RequestBody Advert obyavleniye) {
// public String logoutPage (#RequestBody String obyavleniye) {
System.out.println("Enter: " + obyavleniye);
this.advertService.addAdvert(obyavleniye);
// return "{\"msg\":\"success\"}";
return "{\"title\":\"Title\",\"price\":\"80\",\"description\":\"normm\",\"date\":\"2016-11-07 18:30:21\",\"authorid\":\"2\",\"category\":\"A\",\"state\":\"new\",\"img1\":\"http\",\"img2\":\"http\",\"img3\":\"http\",\"img4\":\"http\"}";
}
My sample code.
js
Company.prototype.saveCompanyLocation = function() {
/* company */
var companyIdx = $('#companyIdx').val();
var locationIdx = $('#locationIdx').val();
var data = {
idx : locationIdx,
postCode : $('#postCode').val(),
address : $('#address').val(),
detailAddress : $('#detailAddress').val(),
tel : $('#tel').val(),
fax : $('#fax').val(),
email : $('#email').val(),
language : $("#language").val(),
latitude : $('#latitude').val(),
longtitude : $('#longtitude').val()
};
data = JSON.stringify(data);
$.ajax({
url : "/gpim/company/settings/location/save/" + companyIdx,
type : 'POST',
data : data,
contentType : 'application/json',
success : function(response) {
if (response == "success") {
document.location.reload(true);
} else {
$("#editMsg").text("you can`t save location information.");
}
},
error : function(request, status, error) {
}
});
};
controller
#RequestMapping(value = "/settings/location/save/{companyIdx}", method = RequestMethod.POST)
public #ResponseBody String saveLocation(#PathVariable int companyIdx, #RequestBody CompanyLocation location) {
Company company = companyService.findCompanyByIdx(companyIdx);
company = companyService.saveCompanyLocation(company, location);
if (company != null) {
return "success";
}
return "fail";
}
Do the below steps:
1) try to keep the jackson jar files in your classpath
2) eighter you have remove the datatype while sending ajax request i.e,
dataType : "json"
or you have to produce the application/json response as below
#RequestMapping(value = "/upload", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
3) Check your DTO or Advert class properties which type should be matched with incoming request. i.e request params should match with DTO members both names and type.
These are possible ways to avoid your case.

passing json to kendoui grid

I would really appreciate guidance.
My script will make a call to my server, grab some data and bring it back as JSON. Then I call ServiceSucceeded(msg); I pass in the JSON results in msg. Now in ServiceSucceeded I want to display my results on kendoui grid. That is the part that I can't get to work. It gives no browser errors.
This code might be awful, so please school me on this , thanks!
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<link rel="stylesheet" href="../../assets/telerik/styles/kendo.common.min.css" />
<link rel="stylesheet" href="../../assets/telerik/styles/kendo.default.min.css" />
<script src="../../assets/telerik/js/jquery.min.js"></script>
<script src="../../assets/telerik/js/kendo.all.min.js"></script>
</head>
<body>
<div id="grid">
</div>
<div>
<script>
var Type;
var Url;
var Data;
var ContentType;
var DataType;
var ProcessData;
var Username;
var Password;
var qryVar;
var locationName;
function GetAllReportDB() {
var dataId = "1";
Type = "GET";
qryVar = "userName=Simon"
Url = "http://localhost/UserReportMap.svc/GetAllReportDB?" + qryVar;
Data = '{"Contains": "Kir","DBName":"Bony","Operator":"BON0D"}';
ContentType = "application/json; charset=utf-8";
DataType = "json"; ProcessData = true;
Username = "test";
Password = "test";
CallService();
}
function CallService() {
$.support.cors = true;
$.ajax({
cache: false,
type: Type, //GET or POST or PUT or DELETE verb
url: Url, // Location of the service
data: Data, //Data sent to server
contentType: ContentType, // content type sent to server
dataType: DataType, //Expected data format from server
processdata: ProcessData, //True or False
beforeSend: function (xhr2) {
xhr2.setRequestHeader("Authorization", "Basic " + window.btoa(Username + ':' + Password));
},
success: function (msg) {
ServiceSucceeded(msg);
alert("Succeeded");
},
error: function (errMsg) {
alert("Fail!");
}
});
}
function ServiceSucceeded(msg) {
var myResults = { "d": [{msg}] };
alert(JSON.stringify(msg));
$(function () {
$("#grid").kendoGrid({
dataType: "json",
schem: {
data: "d"
}
//columns: [{ title: "First Name" },
// { title: "Last Name" }]
});
});
}
$(document).ready(
function () {
GetAllReportDB();
}
);
</script>
</div>
</body>
</html>
Well, you have one typo at schem. It should be schema and not schem.
Anyway, I recommend check API docs, there is written what you need.
And to your question:
You are missing dataSource in your grid so it doesn't know from what data grid should be rendered.
$("#grid").kendoGrid({
dataSource: {
type: "json",
data: jsonData,
pageSize: 20
},
...
});
So line var myResults = { "d": [{msg}] }; can be removed and msg data can be assigned into dataSource. Then you will be able to set columns - here demo
And also consider, if you need load your json data in function and result assign into variable. Grid is able to load data from server without that - server just has to return json data, like in this example

Json Data Not mapped in the backend service

I have a Spring MVC web application and I have the following web service.
#RequestMapping(value = "/newBill", method = RequestMethod.POST)
public #ResponseBody ModelMap acceptNewBill(#ModelAttribute ("Bill") Bill newBill ){
Bill bill = new Bill();
bill.setTableName(newBill.getTableName());
bill.setRoom(newBill.getRoom());
bill.setCovers(newBill.getCovers());
ModelMap model = new ModelMap();
model.put("status", true);
return model;
}
The following Script performs the front end functions.
$('.done').click(function(){
var jsonObject = createJSON(".newBill");
jQuery.ajax({
url: "/newBill",
type: "POST",
data: {bill: JSON.stringify(jsonObject) },
dataType: "json",
beforeSend: function(x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("application/j-son;charset=UTF-8");
}
},
success: function(result) {
alert('sadgsd');
}
});
});
function createJSON(elementToConvert) {
jsonObj = [];
$( elementToConvert + " input").each(function() {
var id = $(this).attr("class");
var email = $(this).val();
item = {}
item [id] = email;
jsonObj.push(item);
});
return jsonObj;
}
The above createJSON function go through a provided html element and puts the values into an object! The click function performs the POST and the Post contains the following data.
bill [{"tableName":"326432"},{"room":"3462346"},{"covers":"3426234"}]
Now when I debug and check the service, the data which goes from the front end doesn't get mapped in the parameter. I checked whether the variable names are the same as the POST. They are the same! but the values doesn't get mapped! Can any one please help me with this issue.
Update :
I changed the service method to GET and passed a value as a URL variable. Then it got mapped in the service param. The problem is in the POST.
Instead of using #ModelAttribute in your controller use #RequestBody:
public #ResponseBody ModelMap acceptNewBill(#RequestBody Bill newBill) {
On the ajax call, set the content type to application/json and stringify the whole object instead of just the array:
jQuery.ajax({
url: "/newBill",
type: "POST",
data: JSON.stringify({bill: jsonObject}),
dataType: "application/json",
beforeSend: function(x) {
if (x && x.overrideMimeType) {
x.overrideMimeType("application/j-son;charset=UTF-8");
}
},
success: function(result) {
alert('sadgsd');
}
});