I have a C#.net method as given below
public string jsonTest()
{
List<string> list = new List<string>();
list.Add("aa");
list.Add("bb");
list.Add("cc");
string output = JsonConvert.SerializeObject(list);
return output;
}
Here eventhough Im creating a Json object by using JsonConvert.SerializeObject I am getting a string (since return type is string).
Can I do like below by using a return type JsonResult (or somthing like that) something like what we can do in MVC?
return Json(new { data = list }, JsonRequestBehavior.AllowGet);
Is it possible to create a Json data in asp.net?
In client side I'm using an ajax call to get data from jsonTest().
$.ajax({
type: 'GET',
url: "test.aspx", //In test.aspx pageload calling jsonTest()
dataType: 'json',
success: function (data) {
alert(data);
},
error: function (data) {
alert("In error");
}
});
When I'm giving dataType: 'json', it will go to error part (Since the ajax expects json data but it gets string). Thats why I want to parse it as a json object in server side.
If ASP.NET,
string output = JsonConvert.SerializeObject(list);
Response.Clear();
Response.ContentType = "application/json; charset=utf-8";
Response.Write(output);
Response.End();
There is nothing called a JSON object. The SerializeObject method returns a string because JSON is nothing more than a string value which follows specific rules.
To return JSON to the browser all you need to do is:
Response.ContentType = "application/json; charset=utf-8";
Response.Write(jsonTest());
Response.End();
I'm going to assume you're trying to create a WebMethod for consumption by a JavaScript XHR call or similiar:
ASP.NET will auto-serialize to JSON for POST requests only (using ASMX or so called "Page Methods"). WCF and WebAPI do not require the POST method, but do require some configuration.
[WebMethod]
public static List<Task> TasksGet(string projectId) {
return MyNamespace.Tasks.GetForProject(projectId);
}
The result your JS call sees would be something like:
{"d": [{
"__type": "MyNamespace.Task",
"id": 1,
"description": "This is my first task"
}, {
"__type": "MyNamespace.Task",
"id": 2,
"description": "This is my second task"
}, {
....etc etc
}
]}
No need to mess around w/ the JsonSerializer class directly.
Also make sure your request headers are set correctly:
Content-Accept: application/json;charset=UTF8
Json is just string data. It is how that string is interpreted. So the fact that it is returning a string is correct. You mentioned ASP.Net. Are you using ASP.Net webforms and looking for a way to return that JSON to the front side?
Related
My app is made in ASP.NET MVC 5. User can use search form which is displaying filtered data. Now I want to add button which will export displayed data.
To do this I am sending Search object to view and save it in html. Now When clicking export button I want to pass this object to controller, get data from database using this Search object and save results as text.
The thing is I cant bind json to c# object. Thats my view:
<div id="originalForm" style="visibility:hidden">
#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))
</div>
This is my ajax code:
function exportRaportToCsv() {
var $formData = $('#originalForm').text();
var allIds = getCheckedIds();
var dataToSend = JSON.stringify({
ids: allIds,
search: $formData
});
$.ajax({
type: "POST",
url: '#Url.Action("ExportToCsv", "BankCosts")',
data: dataToSend,
contentType: "application/json; charset=utf-8",
success: function (datar) {
window.location = '/BankCosts/Download?fileGuid=' + response.FileGuid
+ '&filename=' + response.FileName;
},
error: function (xhr) {
},
});
}
And this is my controller:
[HttpPost]
public ActionResult ExportToCsv(string[] ids, Search search)
{
// search is null here
}
When I spy sending data with Fiddler I can see, that I am passing this:
{"ids":[],"search":"\n {\"ID\":0,\"DateFrom\":\"2018-06-23T00:00:00\",\"DateTo\":\"2018-06-25T00:00:00\",\"hasUnrecognizedStatus\":false,\"skippedSearchResults\":0,\"paginationLimit\":100}\n"}
I think it is worth to mention, that ids is properly passed. If it contains data, that data is passed. I think the problem is that I have \ in my json. How can I remove this? Is there something wrong with my ajax?
When I use console.log to print $formData I can see that \ characters are gone and it looks better:
{"ID":0,"DateFrom":"2018-06-23T00:00:00","DateTo":"2018-06-25T00:00:00","hasUnrecognizedStatus":false,"skippedSearchResults":0,"paginationLimit":100}
[HttpPost]
public ActionResult ExportToCsv(string[] ids,[FromBody]Search search)
{
}
Try adding FromBody if your Search model is ok it should work.
based on your comments, I think that search object already stringified, so you don't need to stringify it.
just make your json like this
var dataToSend = {
"ids": allIds,
"search": $formData
};
Use JSON.parse() to transforms JSON string to a JavaScript object. Your $('#originalForm').text() is a JSON string actually.
var $formData = JSON.parse($('#originalForm').text());
var allIds = getCheckedIds();
var dataToSend = JSON.stringify({
ids: allIds,
search: $formData
});
In your case, $formData is a string (JSON string actually). So JSON.stringify() again trying to convert to JSON string which is already a JSON string that's causing unnecessary '/' character in form data that you are posting.
Make sure to set the content type to 'application/json' in ajax call properties Otherwise MVC model binder will not be able to map and fill .NET model from JSON posted data.
contentType: "application/json; charset=utf-8",
Since you are using
JSON.stringify
the search value posted in string format not object
Search
so
Try replace your controller with this
[HttpPost]
public ActionResult ExportToCsv(string[] ids, string search)
{
//then deserialize search json like
Search objSearch = JsonConvert.DeserializeObject<Search>(search);
}
or
[HttpPost]
public ActionResult ExportToCsv(string[] ids, JObject search)
{
//then deserialize search json like
Search objSearch = JsonConvert.DeserializeObject<Search >
(dataModel["search"].ToString());
}
View
$.ajax({
type: "POST",
url: '#Url.Action("ExportToCsv", "BankCosts")',
data:{ids= allIds.toString(),search:JSON.stringify($formData)}
contentType: "application/json; charset=utf-8",
success: function (datar) {
window.location = '/BankCosts/Download?fileGuid=' + response.FileGuid
+ '&filename=' + response.FileName;
},
error: function (xhr) {
},
});
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)
In MVC, why does returning Content sometimes fail in the Ajax callback, while returning Json works, even for simple string objects?
Even when it fails, the data is still available if you were to access it in the always callback...
Update:
When I set the contentType in the ajax call to text/xml the response will no longer enter the error message.
AJAX:
$.ajax({
cache: false,
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: 'json',
url: "/MyController/GetFooString",
data: { },
success: function (data) {
alert(data);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Ajax Failed!!!");
}
}); // end ajax call
Controller Action That Fails (Sometimes)
Even when it fails, the data is still available.
public ActionResult GetFooString()
{
String Foo = "This is my foo string.";
return Content(Foo);
} // end GetFooString
Controller Action That Always Works
public ActionResult GetFooString()
{
String Foo = "This is my foo string.";
return Json(Foo, JsonRequestBehavior.AllowGet);
} // end GetFooString
Using Content(Foo); sends a response that doesn't have the mime type header. This happens because you're not setting ContentType when using this overload. When the Content-Type is not set, jQuery will try to guess the content type. When that happens, whether it can successfully guess or not depends on the actual content and underlying browser. See here:
dataType (default: Intelligent Guess (xml, json, script, or html))
Json(...) on the other hand explicitly sets the content type to "application/json" so jQuery knows exactly what to treat the content as.
You can get consistent result from Content if you use the 2nd overload and specify a ContentType:
return Content(Foo, "application/json"); // or "application/xml" if you're sending XML
But if you're always dealing with JSON, then prefer using JsonResult
return Json(Foo, JsonRequestBehavior.AllowGet);
I am passing json data to my generic handler page GenericHandler.ashx.cs using jquery ajax request and json as data type.
in my handler code i would like to return html table in string format. here is snap of my handler code
context.Response.ContentType = "text/plain";
context.Response.Write(sResponse);
where sResponse contains <table><tr><td>PropertyName</td><td>PropertyID</td></tr><tr><td>abc</td><td>1</td></tr></table>
my jquery code (check inline comment in error function):
id = { 'PropertyID': id };
$.ajax("Handlers/GenericHandler.ashx?Type=getProperties",
{
type: 'post',
dataType: 'json',
cache: false,
contentType: "application/json",
data: JSON.stringify(id),
success: function (data) {
console.log(data);
},
error: function (xhr, status) {
console.log(status); // Output as parseError
console.log(xhr.responseText); // My sResponse string ! But Why Here ?
}
});
My Question :
Why i am not getting response in success function
Is it right way to do ? or should i convert html table to json object and then return it. And again display it in tabular format ?
From jQuery documentation here, you can see that the dataType parameter is what AJAX is expecting back as a response from the server. The contentType parameter is what is put in the header in your request to the server so that the server knows how to read the request.
Therefore, you should change your dataType to "text" like:
$.ajax("Handlers/GenericHandler.ashx?Type=getProperties",
{
type: 'post',
cache: false,
dataType: 'text',
contentType: "application/json",
data: JSON.stringify(id),
success: function (data) {
console.log(data);
},
error: function (xhr, status) {
console.log(status);
console.log(xhr.responseText);
}
});
I find this useful when alerting of a successful INSERT or UPDATE call on a database. It would be extraneous to create and return a JSON object for such a task.
Your response isn't valid JSON sine it's returning plain text. jQuery is expecting the response to be JSON because you've set contentType: "application/json"
If the rest of your site uses JSON as a transmission format, then wrap your HTML as a JSON object and return it.
In your back end code, return something that looks like this
{response_html : "<table><tr><td>PropertyName</td><td>PropertyID</td></tr><tr><td>abc</td><td>1</td></tr></table>"}
And in your jQUery code, you can access it in the success callback.
success: function (data) {
console.log(data.response_html);
},
NOTE - You'll need to remove the plain text content type from your backend code and make that JSON.
If you tell $.ajax that you expect a JSON, then a text/plain response from the server is not a valid response.
Regarding your second question: The good way to do it would be to return the data you want to work with, in JSON format, for example:
[
{ "label" : "PropertyName", "value" : "abc" },
{ "label" : "PropertyId", "value" : "1" }
]
And then in the success callback of your Ajax request, work with that data to build your HTML structure with jQuery.
After trying to format my JSON data by hand in javascript and failing miserably, I realized there's probably a better way. Here's what the code for the web service method and relevant classes looks like in C#:
[WebMethod]
public Response ValidateAddress(Request request)
{
return new test_AddressValidation().GenerateResponse(
test_AddressValidation.ResponseType.Ambiguous);
}
...
public class Request
{
public Address Address;
}
public class Address
{
public string Address1;
public string Address2;
public string City;
public string State;
public string Zip;
public AddressClassification AddressClassification;
}
public class AddressClassification
{
public int Code;
public string Description;
}
The web service works great with using SOAP/XML, but I can't seem to get a valid response using javascript and jQuery because the message I get back from the server has a problem with my hand-coded JSON.
I can't use the jQuery getJSON function because the request requires HTTP POST, so I'm using the lower-level ajax function instead:
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
data: "{\"Address\":{\"Address1\":\"123 Main Street\",\"Address2\":null,\"City\":\"New York\",\"State\":\"NY\",\"Zip\":\"10000\",\"AddressClassification\":null}}",
dataType: "json",
success: function(response){
alert(response);
}
})
The ajax function is submitting everything specified in data:, which is where my problem is. How do I build a properly formatted JSON object in javascript so I can plug it in to my ajax call like so:
data: theRequest
I'll eventually be pulling data out of text inputs in forms, but for now hard-coded test data is fine.
How do I build a properly formatted JSON object to send to the web service?
UPDATE: It turns out that the problem with my request wasn't the formatting of the JSON, as T.J. pointed out, but rather that my JSON text didn't conform to requirements of the web service. Here's a valid JSON request based on the code in the WebMethod:
'{"request":{"Address":{"Address1":"123 Main Street","Address2":"suite 20","City":"New York","State":"NY","Zip":"10000","AddressClassification":null}}}'
This brought up another question: When is case sensitivity important in JSON requests to ASP.NET web services (ASMX)?
The answer is very easy and based on my previous posts Can I return JSON from an .asmx Web Service if the ContentType is not JSON? and JQuery ajax call to httpget webmethod (c#) not working.
The data should be JSON-encoded. You should separate encode every input parameter. Because you have only one parameter you should do like following:
first construct you data as native JavaScript data like:
var myData = {Address: {Address1:"address data 1",
Address2:"address data 2",
City: "Bonn",
State: "NRW",
Zip: "53353",
{Code: 123,
Description: "bla bla"}}};
then give as a parameter of ajax request {request:$.toJSON(myData)}
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
data: {request:$.toJSON(myData)},
dataType: "json",
success: function(response){
alert(response);
}
})
instead of $.toJSON which come from the JSON plugin you can use another version (JSON.stringify) from http://www.json.org/
If your WebMethod had parameters like
public Response ValidateAddress(Request request1, Request myRequest2)
the value of data parameter of the ajax call should be like
data: {request1:$.toJSON(myData1), myRequest2:$.toJSON(myData2)}
or
data: {request1:JSON.stringify(myData1), myRequest2:JSON.stringify(myData2)}
if you prefer another version of JSON encoder.
Your problem breaks down into two parts:
Creating the JSON string
Your JSON in your quoted code is perfectly valid. But being hand-crafted is a pain. As others have called out, the easiest way to do this is to create a Javascript object and then JSON.stringify it. Example:
var data = {
"Address": {
"Address1": "123 Main Street",
"Address2": null,
"City": "New York",
"State": "NY",
"Zip": "10000",
"AddressClassification": null
}
};
data = JSON.stringify(data);
The first step above creates an object using Javascript object literal notation, which is a superset of JSON (as used above, it actually is the same as JSON, but ignore that). The second bit takes that object and converts it to a string.
Of course, the values above are literal strings, which is unlikely. Here's what it would look like if you had each of those values in a variable:
var data = {
"Address": {
"Address1": address1,
"Address2": address2,
"City": city,
"State": state,
"Zip": zip,
"AddressClassification": null
}
};
data = JSON.stringify(data);
Either way, now you have the string.
Sending the JSON string to the web service
You need to find out is whether the web service is expecting the JSON-formatted data to be the POST body, or if it's expecting the JSON data to be the value of a parameter in the more common name=value URL-encoded POST data. I would tend to expect the former, because the web service seems specifically designed to work with JSON-formatted data.
If it's supposed to be the POST body, well, I've never done that with jQuery, and what you have quoted looks correct to me reading the docs. If it's not working, I'd double-check that your object structure is really what they're expecting to see. For instance, if it's just validating a single address, I wonder if it's expecting to receive just an Address object, rather than an object containing an Address object, e.g.:
{
"Address1": "123 Main Street",
"Address2": null,
"City": "New York",
"State": "NY",
"Zip": "10000",
"AddressClassification": null
}
If it's supposed to be the value of a parameter in boring old URL-encoded multipart form data, then:
$.ajax({
type: "POST",
url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
data: "paramname=" + encodeURIComponent(data),
dataType: "json",
success: function(response){
alert(response);
}
})
I've removed the contentType so jQuery will fall back to its default ("application/x-www-form-urlencoded") and ensured the string we created above is properly encoded in that content type. You'll need to find out the paramname to use (perhaps "Address" and see my earlier comment about sending just the address, rather than an object containing an address child object?).
JSON.stringify will take a javascript object and turn it into a string. I bet though that if you create a Javascript object like
var jsonData = {
address: 'address',
address1: 'address1',
address2: 'address2'
};
and then pass in jsonData as 'data' in the ajax call, then it will convert the object to json text for you.
I would create a javascript object and then call JSON.stringify to turn it into valid JSON. You can download it from here.
You could do something like this:
var address= {};
address["Address1"] = "your val";
address["Address2"] = "your val";
address["City"] = "your val";
address["State"] = "your val";
address["Zip"] = "your val";
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
data: JSON.stringify(address),
dataType: "json",
success: function(response){
alert(response);
}
});
You need to pass it like this:
$.ajax({
type: "POST",
url: "WebService.asmx/WebMethodName",
data: "{'fname':'dave', 'lname':'ward'}",
contentType: "application/json; charset=utf-8",
dataType: "json"
});
Have a look at this article for more details: 3 mistakes to avoid when using jQuery with ASP.NET AJAX
All apologies if this answer comes too late, or is a duplication.
From what I understand, it appears as though you're trying to send just the string of a JSON object. Try building an object and then working with its properties and sending it in as it is.
Example:
address = new Object();
address.Address = new Object();
address.Address.Address1 = "123 Main Street";
address.Address.Address2 = "";
address.Address.City = "New York";
address.Address.State = "NY";
address.Address.Zip = "10000";
address.Address.AddressClassification = null;
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "http://bmccorm-xp/HBUpsAddressValidation/AddressValidation.asmx/ValidateAddress",
data: address,
dataType: "json",
success: function(response){
alert(response);
}
});
Get yourself a jquery plugin that can convert any javascript object to json. For example:
http://plugins.jquery.com/project/json