Send generic JSON data to MVC2 Controller - json

I have a javascript client that is going to send json-formatted data to a set of MVC2 controllers. The client will format the json, and the controller will have no prior knowledge of how to interpret the json into any model. So, I can't cast the Controller method parameter into a known model type, I just want to grab the generic json and pass it to a factory of some sort.
My ajax call:
function SendObjectAsJSONToServer(object,url,idForResponseHTML) {
// Make a call to the server to process the object
var jsonifiedObject = JSON.stringify(object);
$.ajax({
url: url // set by caller
, dataType: 'json'
, data: jsonifiedObject
, type: 'GET'
, error: function(data) { alert('error in sendObjectAsJSONToServer:' + data); }
, success: function(data) {
alert(data.message); // Note that data is already parsed into an object
}
});
}
My MVC Controller:
public ActionResult SaveForm(string obj)
{
// Ok, try saving the object
string rc = PassJSONToSomething(obj.ToString());
string message = "{\"message\":\""+rc+"\",\"foo\":\"bar\"}";
return new ContentResult { Content = message, ContentType = "application/json" };
}
The problem is that obj is always null. Can anyone tell me how I should structure the ajax call and the controller parameter so that I get my json to the server? I'm using MVC2. This may appear to be a duplicate of some SO questions, but in my case I do not know the Model that the json maps to, so I can't use a specific model type in the controller parameter type.
Thanks very much.

Have you tried something like that?
$.ajax({
url: url // set by caller
, dataType: 'json'
, data: {obj :jsonifiedObject}
, contentType: 'application/json; charset=utf-8'
, type: 'GET'
, error: function(data) { alert('error in sendObjectAsJSONToServer:' + data); }
, success: function(data) {
alert(data.message); // Note that data is already parsed into an object
}
});

Related

ASP MVC Areas and JSON POST

I have a project with areas and would like to post a view model as JSON to a controller method.
This is what I have, with performance being generated in the default area and passed to the view in area SeatSelection:
$("#addToCartButton").click(function () {
var json = #Html.Raw(Json.Encode(performance));
$.ajax({
url: 'https://#(Request.Url.Host)/SeatSelection/Home/AddToCart',
type: 'POST',
dataType: 'json',
data: json,
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert(data);
}
});
});
And the action method for testing:
[System.Web.Http.Route("SeatSelection_AddToCart")]
[System.Web.Http.HttpPost]
public JsonResult AddToCart(PerformanceViewModel performance)
{
return Json(performance.Name);
}
I created the following route:
context.MapRoute(
"SeatSelection_AddToCart",
"SeatSelection/Home/AddToCart",
new { action = "AddToCart", controller = "Home", id = UrlParameter.Optional },
namespaces: new string[] { "myProject.Areas.SeatSelection.Controllers" }
);
But all I get is a internal server error 500. I also tried to use [FromBody] and setting a breakpoint to the method, but it is not invoked. I can't figure out what's wrong or missing, please help.
UPDATE
This is the json / performance:
PerformanceID=00000000-0000-0000-0000-000000000000&Name=Performance+15&StartDate=%2FDate(1360364400000)%2F&EndDate=%2FDate(1500328800000)%2F&LatestDateBookable=%2FDate(1450911600000)%2F&Organizer=Organizer+15&Location=Location+15&Availability=75&IsFull=false&IsBookable=true&HasPrice=true&BookableSeats=11&BookedSeats=94&Description=Description+of+Performance+15&Price=443
I found an error: "invalid json primitive: performanceid"
First of all, I would recommend you to use #Url.Action helper method instead of generating url like this: https://#(Request.Url.Host)/SeatSelection/Home/AddToCart.
Secondly, always validate params which comes from the browser. return Json(performance.Name) looks suspicious. What is performance will be null? This might be a problem of your internal server error 500.
If this is not a problem then try to send string instead of JSON to the server and validate and parse JSON on the server side.
You can use Url.Action method like this. I suppose SeatSelection is an area in your project.
$.ajax({
url: '#Url.Action("AddToCart", "Home", new { Area = "SeatSelection"})',

Watson SpeechToText Java and javascript model differences

I'm working on integrating the watson-speech.js javascript library with a Spring-based server using the Watson Java SDK. I'm trying to send the output from a WatsonSpeech.SpeechToText.recognizeMicrophone call to the server with no luck. The Speech java classes appear to have the appropriate #SerializedName annotations that match the json being sent from the client, but I'm getting UnrecognizedPropertyException errors from Jackson.
Unrecognized field "keywords_result" (class com.ibm.watson.developer_cloud.speech_to_text.v1.model.SpeechResults), not marked as ignorable (2 known properties: "resultIndex", "results"])
Here's the controller method:
#RequestMapping(value = "/postWatsonRequest", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonRequest(#RequestBody SpeechResults speechResults) {
...
}
I'm clearly missing something. Do I need to unpack the json manually on the server side (custom deserializer?) or format it into an acceptable json string on the client side?
It turned out to be a couple of mistakes on my part and although I'm not sure this is the best solution it does work. Here's the full code for anyone that's interested. Key things that made it work:
You must use the receive-jason event to capture the full json result. The data event appears to only return the final text
The result data had to be wrapped in a valid json wrapper - data:{message:data} (this was my big mistake)
Do not include contentType: 'application/json; charset=utf-8', in the ajax call or the controller will not recognize the json data
The Watson Java SDK WebSocketManager receives an okhttp3.ResponseBody from Watson from which it extracts a string. I presume this is similar to what the javascript SDK receives so I used the same code from the WebSocketManager to convert the JSON.stringify string to a SpeechResults object in the controller.
From the okhttp3.ResponseBody javadoc:
A one-shot stream from the origin server to the client application with the raw bytes of the response body
Watson javascript
function listen(token) {
stream = WatsonSpeech.SpeechToText.recognizeMicrophone({
token: token,
readableObjectMode: true,
objectMode: true,
word_confidence: true,
format: false,
keywords: keywordsArray,
keywords_threshold : 0.5,
continuous : false
//interim_results : false
//keepMicrophone: navigator.userAgent.indexOf('Firefox') > 0
});
stream.setEncoding('utf8');
stream.on('error', function(err) {
console.log(err);
stream.stop();
});
stream.on('receive-json', function(msg) {
console.log(msg);
if (msg.state != 'listening') {
if (msg.results[0].final) {
console.log('receive-json: ' + msg);
postResults(msg);
stream.stop();
}
}
});
}
Ajax post
function postResults(results) {
var data = JSON.stringify(results);
console.log('stringify: ' + data);
$.ajax({
type: 'POST',
url: appContextPath + '/postWatsonResult',
dataType: 'json',
data: {message:data}
})
.done(function(data) {
console.log('done data: '+ data);
})
.fail(function(jqXHR, status, error) {
var data = jqXHR.responseJSON;
console.log('fail data: '+ data);
});
}
Spring controller
#RequestMapping(value = "/postWatsonResult", method = RequestMethod.POST)
#ResponseBody
#ResponseStatus(value=HttpStatus.OK)
public ResponseObject postWatsonResult(#RequestParam("message") String message, Locale locale) {
logger.info("postWatsonRequest");
JsonObject json = new JsonParser().parse(message).getAsJsonObject();
SpeechResults results = null;
if (json.has("results")) {
results = GSON.fromJson(message, SpeechResults.class);
}
if (results != null) {
logger.debug("results: " + results.getResults().get(0).getAlternatives().get(0).getTranscript());
}
return new ResponseObject();
}
I still think it should be possible somehow to use #RequestBody SpeechResults speechResults so I'll continue to play around with this, but at least I have a working solution.

Why can I not extract the data from this basic JSON Example

This is my Java script
function displayCustomerData( p_customername )
{
$.ajax({
url: 'myservlet',
type: 'GET',
data: { requesttype : "getcustomerdata" ,
customername : p_customername } ,
contentType: 'application/json; charset=utf-8',
success: function ( data )
{
$("#usernametxt").val( data.customer);
},
error: function () {
alert("Error loading customer data");
}
});
on the server side I generate the JSON using the Gson library
Gson gson = new Gson();
return gson.toJson( customerData );
customerData is a simple POJO with two String fields
I have a breakpoint at the Success response from the server
This is what the "data" variable contains in my debugger when I try to get the data from it
data "{"customer":"cuatomer A","userName":"user A"}"
but on my browser console when I do "data.customer" it tells me that customer is undefined ?
This indicates that there is something wrong with the JSON data but I don't see anything wrong and I can't stare at it any longer... anyone see anything?
I have tried it on Chrome and Firefox incase it was a browser issue, same problem on both.
you can parse the Data like using JSON.parse(data) and try for data.customer u can get .the result ....
function displayCustomerData( p_customername )
{
$.ajax({
url: 'myservlet',
type: 'GET',
data: { requesttype : "getcustomerdata" ,
customername : p_customername } ,
contentType: 'application/json; charset=utf-8',
success: function ( data )
{
var data1 = JSON.parse(data);
$("#usernametxt").val( data1.customer);
},
error: function () {
alert("Error loading customer data");
}
});

How to send multiple parameters from kendo data source read operation to WebApi controller

I have the following scenario: I have a kendo.dataSource which is populated via read request to a WebApi Controller. In addition to the read, I am sending a couple of parameters, which then I use in my controller to do some server logic. I was able to send as many simple parameters as I want via the parameterMap property of the transport function. Till now it was a simple get request. However now I need to send additional json object to the controller as a parameter. I read that I have to transform the Get request to Post and put the Json onto the body of the request but I don't know how to do it.
The code that I have so far:
var gridDataSource = new kendo.data.DataSource({
type: 'odata-v4',
transport: {
read: {
url: wave.alarmsAndEvents.api('api/alarmsAndEventsSearch/post'),
type: "POST",
data: {
SearchModel: JSON.stringify(vm.searchModel)
},
contentType: 'application/json; charset=utf-8',
},
parameterMap: function (data, operation) {
if (operation === "read") {
data.startDate = kendo.toString(vm.selectedTimeInterval.start, "G");
data.endDate = kendo.toString(vm.selectedTimeInterval.end, "G");
data.alarmsToDisplay = vm.maxRecords;
}
return kendo.stringify(data);
}
},
pageSize: vm.maxRecords,
error: function (e) {
alert(e.xhr.responseText);
}
});
The SearchModel is the thing that I want to send as JSon. The rest are simple DateTime and int parameters.
My controller:
[HttpPost]
public IQueryable<AlarmsSearchViewModel> Post(DateTime startDate, DateTime endDate, int alarmsToDisplay, [FromBody]JToken jsonbody)
{
....
return something;
}
I end up with Not Found 404, but I am pretty sure that I have messed up the parameters. And from the Network window I can see that the json object is not sent at all. Any help will be much appreciated!

ASP MVC 3 complex multi parameters kno

in my previos question Asp MVC 3 json complex object not initialize properties
My mistake was in JSON convert from Knockout and after one more time with JSON.stringify(data).
Now evering working fine with one parameter,
but I wonder about if I need send to MVC controller two or more parameters one of them is knowckout data = ko.toJSON(viewModel); variable other one is some text.
var settings = ko.toJSON(viewModel);
var parameters = JSON.stringify({ id : *"guid"*, data : settings });
$.ajax({
url: '/KioskAjax/SaveSettings/',
type: "POST",
data: parameters,
dataType: "JSON",
contentType: "application/json; charset=UTF-8",
success: function (result) {
alert('ok');
}
});
[HttpPost]
public JsonResult SaveKiosksSettings(Guid id, GlobalData data)
{
return Json(false.ToString(), JsonRequestBehavior.AllowGet);
}
In this example id is getting value, but GlobalData parameters is null again,
i think this is because I use JSON.stringify again, but how build correct JSON for controller call if I have knowckout object ?
thanks.
ko.toJSON(myObject) does a ko.toJS(myObject) and then a JSON.stringify(myObject).
So, you could choose to use ko.toJS(myObject) to get a clean copy of your data and then JSON.stringify it with your other data, as you are already doing.