JsonResult interpreted as string by browser - c#

I have a controller action like this (very simplified):
[HttpPost]
public JsonResult Submit()
{
Response.StatusCode = Convert.ToInt32(HttpStatusCode.BadRequest);
return new JsonResult
{
ContentEncoding = Encoding.Default,
ContentType = "application/json",
Data = new {error = "xxxxxxxxxx"}
};
}
The point is just that I want to return json, but the result in the browser is string.
Here is the property from the returned object:
To use this now, I have to do something like JSON.Parse, and I don't really want that. The controller action should just return json by itself.
I have previously seen a responseJSON property on the result object from the ajax request in JavaScript.
EDIT:
I'm using the jQuery form plugin, so technically it is that who makes the request.
Here is the code where I initialize the jQuery Form Plugin:
function initializeAjaxForm() {
var feedback = document.getElementById('feedback');
$('#upload-form').ajaxForm({
url: '/xxxx/Submit',
type: 'POST',
beforeSubmit: handleBeforeSubmit,
beforeSerialize: handlePreSerialize,
success: function (data) {
stopLoadingGif();
feedback.innerHTML = 'Yay!';
console.log(data);
},
error: function (data) {
debugger;
console.log(data);
stopLoadingGif();
feedback.innerHTML = 'Nay!';
}
});
}
Here is the request in the browser:
EDIT 2:
Here is the response headers:
EDIT3:
This only seems to be a problem in the error handler.

return JSON object not JSONResult like this:
return Json(new { error = "xxxxxxxxxx"},JsonRequestBehavior.AllowGet);
Have a look at this article

Related

How to pass data to ajax function with json?

I need to get an id from the URL , comment value from textbox, save it to database and show on page with ajax.
Im not sure how should look correct syntax in my controller and ajax function.
Controller
[HttpPost]
public JsonResult AddComment(int id, string comment)
{
if (ModelState.IsValid)
{
return Json(true); // what should be here
}
return Json(true);
}
Ajax
$('#submit').click(function () {
$.ajax({
url: '/Form/AddComment',
method: 'POST',
data: {
id: 4, //how to get id from url?
comment: 'test' //how to get textbox value?
},
success: function (data) {
console.log(data)
},
error: function (a, b, c) {
console.log('err')
}
})
});
this just show me that it work but i dont know how to move forward
Based upon your requirement, you would have to do the appropriate form handling at client side in order to get your variables like id and comment. You can use strongly typed model binding to get your form values and process them on submit or you can use JavaScript techniques to process your form variables. To extract out id from a URL, you can use a Regular Expression or other JavaScript string parsing techniques. I am giving you a simple example of getting your id from a URL and comment from a text box using JavaScript:
Your input control would look like:
<input type="text" id="commentBox" name="Comment" class="form-control" />
In order to achieve your desired functionality using AJAX to POST your form variables to controller, refer to the following code snippet:
AJAX:
<script type="text/javascript">
var url = 'http://www.example.com/4'; //Example URL string
var yourid = url.substring(url.lastIndexOf('/') + 1);
var yourcomment= document.getElementById('commentBox').value;
var json = {
id: yourid, //4
comment: yourcomment
};
$('#submit').click(function (){
$.ajax({
url: '#Url.Action("AddComment", "Form")',
type: "POST",
dataType: "json",
data: { "json": JSON.stringify(json)},
success: function (data) {
console.log(data)
},
error: function (data) {
console.log('err')
},
});
};
</script>
And you can get your values in your Controller like this:
using System.Web.Script.Serialization;
[HttpPost]
public JsonResult AddComment(string json)
{
if (ModelState.IsValid)
{
var serializer = new JavaScriptSerializer();
dynamic jsondata = serializer.Deserialize(json, typeof(object));
//Get your variables here from AJAX call
string id= jsondata["id"];
string comment=jsondata["comment"];
// Do something here with your variables.
}
return Json(true);
}
My solution looks like this:
controller:
[HttpPost]
public JsonResult AddComment(int id_usr,string comment)
{
if (ModelState.IsValid)
{
Comments kom = new Comments();
kom.DateComment = DateTime.Now;
kom.Id_usr = id_usr;
kom.Comment = comment;
db.Comments.Add(kom);
db.SaveChanges();
return Json(kom);
}
return Json(null);
}
View
var url = window.location.pathname;
var idurl = url.substring(url.lastIndexOf('/') + 1);
$('#submit').click(function () {
console.log('click')
$.ajax({
url: '/form/AddComment',
method: 'POST',
data: {
comment: $("#Comments_Comment").val(),
id_usr: idurl,
},
success: function (data) {
console.log(data),
thank you all for guiding me to the solution

Why ajax call not returning success or error though controller sends data?

I have an Ajax call of 'GET' type which is hitting the mvc controller action properly. The controller action type is 'JsonResult' and it is returning json data which should indicate success for the ajax call. But the ajax call is not responding for success or error.
$.ajax({
url: baseUrl + '/Controller_Name/Action_Name',
type: 'GET',
data: param,
success: function (data) {
var response = JSON.parse(data);
if (response.length > 0 && response != '-1') {
toastr.options.timeOut = 2500;
toastr.success('Data retrieved successfully', 'Success');
}
},
error: function (xhr) {
toastr.options.timeOut = 2500;
toastr.warning('Error while retrieving data', 'Error');
}
});
The controller action type is 'JsonResult' and it is returning json data which should indicate success for the ajax call
When we return JSONResult we get json object in the callback, so we don't need to Parse it. If the action returns like following:
public ActionResult YourAction()
{
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
then in success the following should work:
success: function (data) {
alert(data.success);
if(data.success === true) {
// do something here
}
}

Getting JSON Object from MVC Controller

What I want is to protect my developer key while making an Ajax call to a cross-domain. Before I would just go straight to the url and plug in my key. Like this
$.ajax({
url: "https://na.api.pvp.net/api/lol/na/v2.3/team/TEAM-ID?api_key=mykey",
type: "GET",
data: {},
success: function (json) {
console.log(json);
console.log(json[teamID].name);
console.log(json[teamID].fullId);
console.log(json[teamID].roster.ownerId);
console.log(json[teamID].tag);
},
error: function (error) {}
});
This would give me the following Object, which I could easily parse out.
However, as mentioned, any person could easily grab my key during this process. So I decided to move this action to my Controller (yes I know there shouldn't be business logic here, but it is more secure and this is a quick process).
So what I am doing now is running my Javascript, which calls the Controller for a Json return.
Javascript
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + teamID,
success: function (json) {
console.log(json);
},
error: function(error) {
}
});
And my Controller takes that in and attempts to return the JSON.
[HttpPost]
public ActionResult teamLookUp(string ID)
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://na.api.pvp.net/api/lol/na/v2.3/team/" + ID + "?api_key=myKey");
myReq.ContentType = "application/json";
var response = (HttpWebResponse)myReq.GetResponse();
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return Json(new { json = text });
}
However during this processs I return a string that is not a JSON object, thus cannot be parsed by my script.
It returns the entire json as one long string.
At this point I tried to add the following to my Controller.
var json2 = JsonConvert.DeserializeObject(text);
return Json(new { json = json2 });
But all that returned was some empty Object.
I have been trial and error'ing, searching, and guessing for the past 4 hours. I have no idea what to try anymore. I just want my Controller to pass back an Object that can be readable again like this. (Or at least some sort of formatted json object)
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + teamID,
success: function (json) {
console.log(json);
console.log(json[teamID].name);
console.log(json[teamID].fullId);
console.log(json[teamID].roster.ownerId);
console.log(json[teamID].tag);
},
error: function (error) {}
});
Your method doesn't appear to need to be a POST as it is just getting data rather than modifying it. Therefore you could set it to be a GET instead.
Example
[HttpGet]
public JsonResult teamLookUp(string ID)
{
// Your code
return Json(text, JsonRequestBehavior.AllowGet);
}
Here's an excerpt from your code:
[HttpPost]
public ActionResult teamLookUp(string ID)
{
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create("https://na.api.pvp.net/api/lol/na/v2.3/team/" + ID + "?api_key=myKey");
myReq.ContentType = "application/json";
// here's how to set response content type:
Response.ContentType = "application/json"; // that's all
var response = (HttpWebResponse)myReq.GetResponse();
string text;
using (var sr = new StreamReader(response.GetResponseStream()))
{
text = sr.ReadToEnd();
}
return Json(new { json = text }); // HERE'S THE ERRING LINE
}
Based on the response you received, I could understand that text already contains you desired JSON.
Now replace return Json(new { json = text }); with Json(text); and that should fix it.
To answer your question in the comments, here's how you can read the response data:
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + teamID,
dataType: "json", // type of data you're expecting from response
success: function (json) {
console.log(json);
console.log(json[teamID].name);
console.log(json[teamID].fullId);
console.log(json[teamID].roster.ownerId);
console.log(json[teamID].tag);
},
error: function (error) {}
});
I think the problem lies where you say return Json(new {json = text;}). That's telling the json serializer to dump all your data into a property in the json obect called 'json', which is what you're seeing in the response.
Try return Json(text) instead.
Ending up using WebClient
[HttpPost]
public ActionResult teamLookUp(string ID)
{
string text = "";
try
{
using (var webClient = new System.Net.WebClient())
{
webClient.Encoding = Encoding.UTF8;
var json2 = webClient.DownloadString("https://na.api.pvp.net/api/lol/na/v2.3/team/" + ID + "?api_key=myKey");
return Json(json2);
}
}
catch (Exception e)
{
text = "error";
}
return Json(new { json = text });
}
And I parsed it like normal,
$.ajax({
url: "/Competitive/teamLookUp",
type: "POST",
data: "ID=" + ID,
dataType: "json",
success: function (resp) {
if (resp["json"] == "error") {
// error reaching server
} else {
// successfully reached server
}
json = JSON && JSON.parse(resp) || $.parseJSON(resp);
var userID = ID;
teamName = json[userID].name;
teamID = json[userID].fullId;
teamCPT = json[userID].roster.ownerId;
teamTag = json[userID].tag;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
// error
}
});
I was having the same issue as the original poster: the ReadToEnd() call result escapes special characters and thus doesn't look like JSON to the receiving end, but then I saw a similar question answered here and thought others reading this might find it helpful as well.
To summarize: Deserializing in the Controller which the original poster tried was key, but also as others have pointed out, the return doesn't need the new {} call.
So pieced together:
using (var sr = new StreamReader(endpointResponse.GetResponseStream())) {
var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
var jsonObject = serializer.DeserializeObject(sr.ReadToEnd());
return Json(jsonObject, JsonRequestBehavior.AllowGet);
}

Controller Action Not Found JSON and ASP.NET MVC

Hi I have this controller method
[HttpPost]
public JsonResult CalculateAndSaveToDB(BMICalculation CalculateModel)
{
if (ModelState.IsValid)
{
CalculateModel.Id = User.Identity.GetUserId();
CalculateModel.Date = System.DateTime.Now;
CalculateModel.BMICalc = CalculateModel.CalculateMyBMI(CalculateModel.Weight, CalculateModel.Height);
CalculateModel.BMIMeaning = CalculateModel.BMIInfo(CalculateModel.BMICalc);
db.BMICalculations.Add(CalculateModel);
db.SaveChanges();
}
var data = new
{
CalculatedBMI = CalculateModel.BMICalc,
CalculatedBMIMeaning = CalculateModel.BMIMeaning
};
return Json(data, JsonRequestBehavior.AllowGet);
}
And this is my JS functions:
$('#good').click(function () {
var request = new BMICalculation();
$.ajax({
url: "CalculateAndSaveToDB",
dataType: 'json',
contentType: "application/json",
type: "POST",
data: JSON.stringify(request), //Ahhh, much better
success: function (response) {
$("#result").text(response.result);
},
});
ShowBMI();
});
function ShowBMI() {
$.ajax({
type: "GET",
dataType: "json",
contentType: "application/json",
url: "CalculateAndSaveToDB",
success: function (data) {
var div = $('#ajaxDiv');
div.html("<br/> " + "<b>" + "Your BMI Calculations: " + "</b>");
printBMI(div, data);
}
});
};
When ShowBMI() is executed, Chrome says GET http://localhost:50279/BMICalculations/CalculateAndSaveToDB/0 404 (Not Found)
The POST works as it saves to the database etc but the GET doesn't? Is there any reason for this? As you can see the URLs are exactly the same in each JS function so Im not sure why its found once nut not again the second time?
UPDATE:
After separating logic, the values appearing on the webpage are both null. See below for code changes
[HttpPost]
public JsonResult CalculateAndSaveToDB(BMICalculation CalculateModel)
{
if (ModelState.IsValid)
{
CalculateModel.Id = User.Identity.GetUserId();
CalculateModel.Date = System.DateTime.Now;
CalculateModel.BMICalc = CalculateModel.CalculateMyBMI(CalculateModel.Weight, CalculateModel.Height);
CalculateModel.BMIMeaning = CalculateModel.BMIInfo(CalculateModel.BMICalc);
db.BMICalculations.Add(CalculateModel);
db.SaveChanges();
}
CalculateAndSaveToDB(CalculateModel.BMICalc.ToString(), CalculateModel.BMIMeaning.ToString());
return Json("", JsonRequestBehavior.AllowGet);
}
[HttpGet]
public JsonResult CalculateAndSaveToDB(string o, string t)
{
var data = new
{
CalculatedBMI = o,
CalculatedBMIMeaning = t
};
return Json(data, JsonRequestBehavior.AllowGet);
}
That's because you've applied the [HttpPost] attribute :) That attribute renders the action available solely for POSTing and not GETing. You should move the logic that is relevant for GETing to an action with the same name but without the [HttpPost] attribute and keep the logic for handling POSTed data in the action marked with the [HttpPost] attribute.
Be advised that you should reconsider the names when separating logic into different methods, or else the names will be misleading.
Regarding your update
I would have the POST request handling action (your action marked with HttpPost) return an ActionResult which in essence would mean that the POST request handling action upon successfully handling your request would redirect the user to a confirmation page or somewhere else. Wherever's preferable really :)
Try to approach it logically, what would be the natural chain of events upon POSTing the data? What would you as a user expect to happen?
Regarding your GET action, that is because you are not sending in the parameters o and t, which you then immediately return. Since nothing happens to these parameters in your logic and they are not otherwise specified, they will contain null which is the default value for variables of type string. Are you not intending to retrieve data from the database, rather than supply two parameters only to immediately return them?

How to read Ajax class response send from a ASP.NET MVC Contoller?

Hello and many thanks for you help! I'm new to Web Programming.
I have an Ajax call to a controller in ASP .NET MVC.
When response received I try to get multiple information from the response and use it on my HTML.
$.ajax({
url: '#Url.Action("Function", "Controller")',
data: JSON.stringify({ Parameter: $(this).attr("id") }),
type: "POST",
contentType: "application/json",
timeout: 10000,
dataType: "json",
success: function (result) {
var result = result.d;
$("#textbox1").attr("value", result.attr1);
$("#textbox2").attr("value", result.attr2);
$("#textbox3").attr("value", result.attr3);
}
The Controller:
public class response
{
public string attr1;
public string attr2;
public string attr3;
}
[HttpPost]
public response Function(String Parameter)
{
response returnVal = new response();
returnVal.attr1 = "Dummy1";
returnVal.attr2 = "Dummy2";
returnVal.attr3 = "Dummy3";
return returnVal;
}
In the controller I receive the information but when the response should be parrsed nothing happen.
I guess an error occurs or I parse the data badly.
Thanks for your answers in advance!
Try changing your return type for the controller method to ActionResult (I have no idea what response is). Then change your return line to this:
return Json(returnVal, JsonRequestBehavior.AllowGet);
Have you tried
public JsonResult Function(String Parameter)
{
response returnVal = new response();
returnVal.attr1 = "Dummy1";
returnVal.attr2 = "Dummy2";
returnVal.attr3 = "Dummy3";
return Json(returnVal);
}

Categories

Resources