I'm trying to post some JSON to a web service. The web-service is executed but there's no data available.
The jQuery looks like this :
var json = {"Results": results};
var jsonArray=JSON.stringify(json);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: requestURL,
data: jsonArray ,
dataType: "json",
success: function (data) { TCG.QUE.processSaveButtonSucceeded(data); },
error: function (data) { TCG.QUE.processSaveButtonFailed(data); }
});
And the webservice implemented in a controller looks like this :
public HttpResponseMessage Post([FromBody]string value)
{
object o1 = Request.Content;
HttpResponseMessage r = new HttpResponseMessage(HttpStatusCode.OK);
return r;
}
If I take out the [FromBody] directive then I get a 404. If I leave it in the code is executed but the value of the value argument is null.
I thought the [FromBody] directive meant the data was contained in the Request object but if it is I can't find it .
Would appreciate any suggestions so that I can access the JSON from the client within the Post method.
UPDATE:
I just re-read this : http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api which made me wonder whether the name I was giving the JSON blog client side should correspond to the name of the argument on which the [FromBody] is applied so I changed the name of the argument from value to Results but still the value within the Post method is null.
RESOLUTION
After reading the blog post referred to by Prashanth Thurairatnam I changed my method to be like this and it works :
public HttpResponseMessage Post([FromBody]JToken jsonbody)
{
// Process the jsonbody
return new HttpResponseMessage(HttpStatusCode.Created);
}
.
Not sure what you are passing into results. Ran into this blog. You may want to give it a go. The blog talks on passing the data as JSON object/ array (you may want to try without JSON.stringify)
Related
NOTE Please see the update at the bottom.
I'm picking up maintenance on an existing (working) application.
The application receives data into a class via a post to a Web API controller action.
However when I try to test this by posting it some data it just gives an empty object.
I assumed that my Json must be wrong so I tried sending the Json string as text and deserializing manually, and this works fine, returning the populated object I would expect to see.
I've searched online and seen various suggestions about adding attributes to the parameters but this doesn't do it for me.
The code looks pretty much as follows:
[HttpPost]
[AllowBasicAuthentication]
public async Task<MyResponse> ProcessData(
[FromUri]string key,
[FromUri]string name,
[FromUri]string value1,
[FromBody] DataClass value // this is never populated
)
{
// the following returns the data as expected
var test = new JavaScriptSerializer().Deserialize<DataClass>(value1);
...
}
The jQuery I'm using to test this is as follows:
$('#post').click(function () {
var key = $('#key').val();
var name = $('#name').val();
var value1 = $('#value').text();
var value = JSON.parse(value1);
var url = '/api/ProcessData/?key=' + key
+ '&name=' + name
+ '&value1=' + value1
/* with this post value appears in action as an instantiated but empty object */
$.post(url, { value: value })
.success(function (r) {
...
})
.fail(function (r) {
...
})
/* also tried the following, but value appears as null object
$.ajax({
url: url,
type: 'POST',
cache: false,
contentType: "application/json",
data: value,
success: function (r) {
alert(r);
}
});
*/
});
[EDIT]
Just to clarify, I added the value1 string parameter to test that the Json can be deserialized correctly, which it can, so the Json is ok and the class is ok.
UPDATE
This works when called from Postman so the error must be in the jQuery.
Can anyone show the correct way to do this?
Thanks
[/EDIT]
I have seen a lot of posts that seem to somewhat address my situation but they all leave me a bit confused.
I have an object that I am POSTing to my Controller. I have the post coming to my controller okay by doing this:
$('#fileSubmit').click(function () {
var filesObj = [];
$('#fileList .files .fileName').each(function () {
var name = $(this).text();
filesObj.push({ 'name': name });
});
$.ajax({
type: "POST",
url: "/FileUpload/ImportCommit",
data: filesObj,
dataType: "json"
});
});
I want to then take that JSON object and put it into a list in my controller. So far here is what i have, but I have not done a lot of coding in C# and don't know what to do next.
[HttpPost]
public ActionResult ImportCommit(List<string> filenames)
{
}
I know my controller method's code is blank, but am not sure what to do next. Any help would be much appreciated. Thanks!
The post data you send via the data field of the ajax method needs to be name value pairs. Asp.Net will map them in the Request Params collection via their name. E.g. if you post an object like this,
{
fileNames: JSON.stringify(arFileNames)
};
It can then be accessed server side via,
string json = HttpContext.Current.Request.Params["fileNames"];
If your json looks something like this,
"{"filenames":["somefile","somefile2","somefile3"]}"
You could use newtonsoft JSON (JSON.Net) to convert it to a list of strings by creatong a class to represent it, like this,
public class JsonResultFileNames
{
[Newtonsoft.Json.JsonProperty(PropertyName = "filenames")]
public string[] FileNames { get; set; }
}
Then convert the json to JsonResultFileNames with,
JsonResultFileNames jsonResult = Newtonsoft.Json.JsonConvert.DeserializeObject<JsonResultFileNames>(jsonStringHere);
Then you have a c# object representing your json data. Also you can get way more complex with this, but the important thing to note with JSON.Net, is it quite literally deserializes into a c# representation. E.g. if you want to deserialize straight to a string array, then there should only be an array of strings in your json (no object/field names etc).
E.g. where I work we have an api that returns results like this,
{
status: {
success: true;
},
customerdata {
id: {some-guid},
name: Some Customer Name
}
}
The problem with that, is my C# class needs to be composed of nested classes, e.g. I need a class to represent status and a class to represent customerdata. Things can get weird naming wise when doing that, I ended up with things like CustomerResponse, CustomerResponseStatus, CustomerResponseData, where CustomerResponseStatus and CustomerResponseData are exposed in CustomerRespnose, and I deserialize the json to the CustomerResponse type.
If your json is just an array of strings, you should be able to use string[] for the type passed into JsonConvert.Deserialize, which would not require you to make response classes to hold the data.
The trick was to modify my AJAX to POST like this:
$.ajax({
type: "POST",
url: "/dat/Controller",
data: JSON.stringify(filesObj),
contentType: "application/json",
traditional: true,
success: function (result) {
console.log("Success: " + result);
},
error: function (result) {
console.log("Error: " + result);
}
});
Changing dataType to contentType and adding traditional: true seemed to do the trick for me. The reason for this (I believe) is because the actual data that I was posting is technically not JSON. I added the traditional: true just to be on the safe side.
Okay, I've seen tons of questions posted regarding this question, but none of the answers has actually worked for me, here's my AJAX:
$.ajax({
url: "/FilterSessions/GetFilterSession",
type: "GET",
dataType: "json",
data: jsonFilters,
traditional: true,
success: function (response) {
//Haha, it's never entering here. not really.
}
});
var "jsonFilters" contains an array with the following data:
[0] = { Path: "Test", Name: "More testing", Value: "Test Value" },
[1] = { Path: "Test", Name: "More testing", Value: "Test Value" }
And this is my controller:
public ActionResult GetFilterSession(List<FilterSessionModel> jsonFilters)
{
//Do things
return Json(false, JsonRequestBehavior.AllowGet);
}
jsonFilters always remains null... I have also tried adding contentType: "application/json; charset=utf-8" to the AJAX call... but that didn't really do anything
Finally, the class FilterSessionModel is structured as follows:
public class FilterSessionModel
{
public string Path { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}
Any ideas as to what I might be missing or what might be happening?
Things I've tried so far:
Setting "traditional: true", setting "contentType", using JSON.stringify and attempting to accept a string in the MVC Controller (no-go)
UPDATE: Thanks to the answer below I realized that what was missing was to send over the data with the param Id like so:
data: "{param1ID:"+ param1Val+"}"
I would try switching out the type on your action.
List<FilterSessionModel>
Pretty sure the above is not going to work, I would try something like Object.
Or possibly a string that I would then use newton json dll to push into your List of Class.
The problem boils down to your action being unable to figure out the type, assuming you are checking your data prior to the ajax get being called.
**Update due to more info. Add in the error portion and view those vars on return from your controller, also fire up fiddler and watch what your are getting for http numbers.
$.ajax({
type: "POST",
url: "Servicename.asmx/DoSomeCalculation",
data: "{param1ID:"+ param1Val+"}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(msg) {
UseReturnedData(msg.d);
},
error: function(x, t, m, b) {
//Look at the vars above to see what is in them.
}
});
I think what you are looking for is answered here:
Passing A List Of Objects Into An MVC Controller Method Using jQuery Ajax
First off I'm making the assumption that your $.ajax is for JQuery and not some other Javascript framework. Please correct me if that's wrong.
ASP.NET MVC can actually do what you are asking it to (resolve data sent via AJAX to a List<FilterSessionModel>, but it seems to have a difficult time doing it via a GET request. It would help to know which version of ASP.NET MVC you are using, as more is required to get this working on the older versions. However, what I'm suggesting should work on MVC 3 or 4.
When you send AJAX via JQuery using a GET request and passing it a JavaScript array, this is what you are sending to the server:
http://localhost:50195/FilterSessions/GetFilterSession?undefined=&undefined=
It's no wonder the model is null because no data is actually being sent.
I believe ASP.NET can accept objects (and even arrays of objects) like this, but it won't do so with it formatted as JSON (like via JSON.stringify) as that just results in the following request:
http://localhost:50195/FilterSessions/GetFilterSession?[{%22Path%22:%22Test%22,%22Name%22:%22TestName%22,%22Value%22:%22Testing%22},{%22Path%22:%22Test%22,%22Name%22:%22TestName%22,%22Value%22:%22Testing%22}]
The way you probably want to do this is with a POST request. ASP.NET MVC will actually accept a JSON string as POST data and will decode it and resolve the model properly. Your AJAX code works fine with a couple modifications:
$.ajax({
url: "/FilterSessions/GetFilterSession",
type: "POST", //Changed to POST
dataType: "json",
data: JSON.stringify(jsonFilters), //Pack data in a JSON package.
contentType: "application/json; charset=utf-8", //Added so ASP recognized JSON
traditional: true,
success: function (response) {
alert('Success!');
}
});
The controller you posted should recognize POST data already, but in case it doesn't, a simple [HttpPost] attribute is all you need:
[HttpPost]
public ActionResult GetFilterSession(List<FilterSessionModel> jsonFilters)
{
//Do things
return Json(false, JsonRequestBehavior.AllowGet);
}
javascript or ajax call never type cast the object. . .you need to set type of the controller side parameter either string or List else you can also set the Object type. . If you modified codein that way.. .Your code definitely work !!!
$.ajax({
url: "/FilterSessions/GetFilterSession",
type: "GET",
dataType: "json",
data:JSON.stringify({ 'jsonFilters': jsonFilters}),
contentType: 'application/json; charset=utf-8',
success: function (response) {
//Do your action
}
});
I need to submit a simple form and validate the model. If the model is valid, I would like to serialize that model and send it via POST to an external (https) web service using custom headers. Finally I would handle the response that I get back from the request and display the appropriate message.
I am validating the model from the controller perfectly and serialize the object but can't seem to find a way to create a JSON post request to the external URI. Is there a way to do this using JQuery.ajax or $.post. Maybe I am missing a key ajax param to achieve this.
Thanks
So based on the clarification on the question this is what you can do:
Define the controller method that will validate the object
public ActionResult TestMethod() {
// do server-side validation
return Json(aValidObject);
}
You do an ajax post to your controller so you can validate your model then get back a json result.
$.ajax({
url: '#Url.Action("TestMethod")',
data: some_data,
type: "post",
success: function (result) {
// result is a valid json object
doExternalPost(result);
}
});
Add custom header and do the external post
function doExternalPost(o) {
$.ajax({
url: 'http://some_external_url',
data: o,
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader('custom_header', 'some_value');
},
success: function() {
// post is sucessful
},
error: function (xhr, errorType, exception) {
var errorMessage = exception || xhr.statusText || xhr.responseText;
alert('An error has occured: ' + errorMessage);
},
});
}
try this
var data = {jsonDataObjectHere};
var request = $.ajax({
url : 'externalUrl.com/something.whatever',
type : 'POST',
data : data // see above
});
request.success(function(response){
// the response is the stuff from the server
});
i'm sleepy so forgive typos
good luck
EDIT: for a bit of clarification, with MVC you really dont need to serialize the json object, mvc will accept it as it is.
I went through dozens of answers to figure out the trick to posting data from $.ajax to a parameter in MVC 2's Controller. Here's as far as I got:
BTW this works if you use a GET, but fails as a POST. How would I fix it?
$(document).ready(function () {
$.ajax({
type: "POST",
url: "/Home/Get",
data: {value:'9/14/2010 12:00:00 AM'},
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert(result.value);
}
});
});
And this is my MVC 2 Controller:
public class strange
{
public string value { get; set; }
}
public JsonResult Get(strange o)
{
var b = new strange { value = "return" };
return Json(b, JsonRequestBehavior.AllowGet);
}
Upon POST, o's "value" is null. Changing POST to GET, o's "value" is "9/14/2010 12:00:00 AM".
How do I get the POST to work with $.ajax?
Did anyone ever post a guide to getting JSON working with MVC2 data validation when returning JSON from the client? I know they had that in their MVC 2 futures a while ago.
The data which you send to the ASP.NET MVC Controller should not be JSON encoded. So you should just remove the line
contentType: "application/json; charset=utf-8",
from the $.ajax request and your program will work.
You need to pass JSON to the controller, and it's looking for a strange object, all you're currently passing is a string called value, instead your data should look like this:
{ strange: { value:'9/14/2010 12:00:00 AM'} }
Notice how strange is not an object with the value property the server is looking for. But, it'll expect this as a string, so just use JSON.stringify() (use JSON2 if needed for other browsers, e.g. < IE8):
data: JSON.stringify({ strange: { value:'9/14/2010 12:00:00 AM'} }),