Using $.getJSON in .NET MVC 3.0 - asp.net-mvc

I want to use jQuery.getJSON function in ASP.NET MVC 3.0, so I wrote the code below for test:
<input id="btn" type="button" />
<script>
$("#btn").click(function () {
$.getJSON("/Location/GetData", null, function (data) {
alert(data);
});
});
</script>
and I have a LocationController with below method:
public JsonResult GetData()
{
List<int> result = new List<int>(){1, 4, 5};
return Json(result);
}
But it doesn't work!
The GetData method calls, but 'alert' is not shown!

You need to tell MVC to allow your JSON action to be called via GETs by changing your return to:
return Json(result, JsonRequestBehavior.AllowGet);
By default (for security reasons) they only allow Json to be requested via POSTs.

To protect against cross-side-scripting attacks & JSON Hijacking, MVC 2+ (I think it was 2), requires that you access actions with JSON responses using POST, rather than GET.
You can override this behaviour by using the overload of Json(), where you set the JsonRequestBehavior.AllowGet flag, but as described in the blog post, this is not a good/safe idea.
The way I do all of my JSON requests, whether they be jsut loading data, or posting back, is to use the $.post jQuery method, and limit the controller action to only accept HttpPost.
so your code would become:
$("#btn").click(function () {
$.post("/Location/GetData", null, function (data) {
alert(data);
});
});
and
[HttpPost]
public JsonResult GetData()
{
List<int> result = new List<int>(){1, 4, 5};
return Json(result);
}

First of all. Install Firebug for Firefox so you can inspect the response the server sends, Chrome and IE has built in tools you can use too.
Without knowing the response I will assume the problem is that ASP.NET MVC protects you against JSON hijacking byt not allowing to return JSON for a GET request by default.
Try changing to:
return Json(result, JsonRequestBehavior.AllowGet);

Related

void ActionMethod call using ajax post request with verificationtoken overwrites page, turning it blank. How come?

I am trying to call an action method without affecting the view. I call the following action method
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public void Index(LoginModel login)//, string returnUrl)
{
if (ModelState.IsValid &&
System.Web.Security.Membership.ValidateUser(login.UserName, login.Password))
{
FormsAuthentication.SetAuthCookie(login.UserName, login.RememberMe);
login.JavascriptToRun = "updateForm()";
}
// handle error
}
by doing this
$('#loginBtn').click(function () {
var success = false;
var form = $('#loginForm');
var token = $('input[name="__RequestVerificationToken"]', form).val();
$.ajax({
url: $(this).data('url'),
type: 'POST',
data: {
__RequestVerificationToken: token,
LoginModel: "#Model"
},
success: function (result) {
alert("logged in");
}
});
});
The form is in a separate view which also contains above JS-code snippet.
Everything works fine except for that the entire page reloads and since the actionmethod is void this turns out blank. I do not want anything to happen to the webpage, only to change js code snippet stored in a model which BTW is an empty function as of now.
I've looked at related posts such as ASP.NET MVC - How to call void controller method without leaving the view? but I am none the wiser.
Feels like I'v hit a wall and others' input would be much appreciated. Cheers!
You can use ActionResult as a data type for Index() Action and use View() to return your javascript into it. (return JavaScriptResult())
Check out this too:
Working example for JavaScriptResult in asp.net mvc

MVC Controller return Content instead of JSON

I've been working on a project were all of my requirements involved JSON. However now suddenly I have a need to return results from my model that can be used in an input elements value field. I can't use the solution I have been as I get objects returned instead of plain text for the value. This is the controller pattern I have been using:
public virtual JsonResult fooData()
{
var fooresults = new fooQueries().fooTotal();
return new JsonResult
{ JsonRequestBehavior = JsonRequestBehavior.AllowGet, Data = fooresults };
}
Is there a way to use return content instead of JsonResult? I'm fairly new to the .NET MVC framework and having some difficulty finding the correct way to do this.
My current results are formatted like this:
[{ "foo", 3 }]
Instead I would prefer to get plain text so that I can use an AJAX request to pass the 3 value into an input elements value="" field.
AJAX call I am using with the controller:
$.ajax({
type: 'GET',
url: $('#fooValue').data('url'),
success: function (data) {
$('#fooValue').val(data);
}
});
The data-url is equivalent to:
../fooController/fooData
I'm just using T4MVC.
Return a ContentResult instead of a JsonResult
public virtual ContentResult gooData()
{
var fooresults = new fooQueries().fooTotal();
return Content(fooresults);
}
You can return content as:
return Content(fooresults);
But this wont be clean to you separate the elements as JSON return is.
I'm not sure what the shape of fooresults is, but you should be able to alter your AJAX call to the following:
$.ajax({
type: 'GET',
url: $('#fooValue').data('url'),
success: function (data) {
$('#fooValue').val(data.foo);
}
});
If the dataType property of the jQuery ajax call isn't explictly set, then jQuery will try and infer the type of the return result based on the MIME type, which in your case will be JSON. Therefore jQuery will deserialise the JSON to a JSON object. See http://api.jquery.com/jQuery.ajax/ for more info.
to return a Json, the method should be changed as follow:
public JsonResult fooData()
{
var fooresults = new fooQueries().fooTotal();
return Json(fooresults , JsonRequestBehavior.AllowGet);
}

$.post() not working if the mvc model view controller has a parameter

I´m new with MVC. I´m using MVC4.
I'm having an issue with a callback. If I alert before and after the post() call both alerts show but the call doesn't fire.
[HttpGet]
[Authorize]
public ActionResult Dashboard(int Menu)
{
//some code
return View("Dashboard");
}
<script>
$(document).ready(function () {
$.post("../Client/GetFact", {},
function (data) {
//some code
});
});
</script>
[HttpPost]
[Authorize]
public JsonResult GetFact()
{
//some code to fill object_data
var data = object_data;
return Json(data);
}
As long as I leave ActionResult Dashboard without a parameter is works. If I add a parameter to Dashboard(int Menu) then the call back to GetFact doesn't work.
I searched and found a similar post and follow the instructions given by you guys, but still does not work( looked at: getJSON not working if the mvc model view controller has a parameter).
I do not know what I'm doing wrong. Can you help? Thank's!
I do something similar with $.get, using jquery with the #Url.Action instead of the url.
in addition to using the FormContext to pass to my Action :
Place just before #using (Html.BeginForm())
#{ ViewContext.FormContext = new FormContext(); }
example :
$.get('#Url.Action("ActionName", "ControllerName")', { IDName: $('#IdName').val() }, function (data) {
//Do Something here with the data
});
I would imagine form post would be
$.post('#Url.Ation("ActionName", "ControllerName")', function (data) {
//Do Something here with the data
});
This is a shorthand Ajax function, which is equivalent to:
$.ajax({ type: "POST",
url: url,
data: data,
success: success,// -> call alert here
dataType: dataType});

jQuery post to another controller

If I have a Controller called "HomeController" and I'm on the Index page of that controller, how can I do a jQuery Ajax post to another controller.
I tried the below,
$.post("/DetailedQuote/jQueryGetDetailedQuote", { productCode: "LPJ" }, function(newHTML) {
alert(88);
});
I have a DetailedQuoteController.
I have also tried;
post("DetailedQuote/
post("DetailedQuote.aspx/
post("/DetailedQuote.aspx/
post("/DetailedQuoteController/
post("DetailedQuoteController/
post("DetailedQuoteController.aspx/
post("/DetailedQuoteController.aspx/
And still no joy.
I should also mention that this is running a Hybrid WebForms and MVC site on IIS 6.
EDIT
The error that is being returned in error: is "error" so I assume that's maybe a 404.
In fact, it is a 404. I just checked.
This should work:
public class DetailedQuoteController : Controller
{
[HttpPost]
public ActionResult GetDetailedQuote(string productCode)
{
return Json(new { Code = productCode, Quote = 123 });
}
}
And to invoke it first declare a global javascript variable containing the address of this controller somewhere inside the view:
var quoteAddress = '<%= Url.RouteUrl(new { controller = "DetailedQuote", action = "GetDetailedQuote" }) %>';
And finally call the method:
$(function() {
$.post(quoteAddress, { productCode: 'LPJ' }, function(json) {
alert(json.Quote);
});
});
There doesn't appear to be anything wrong with your jQuery command, so the most obvious place to start looking is in the controller itself. Things to check would be:
Does your Controller action return a Json response (e.g. public JsonResult jQueryGetDetailedQuote)?
Are you using the Json() method to return your object?
Do you have your action decorated with the [HttpPost] attribute?
Perhaps you could post part of your controller code as well?
I notice that in your jQuery method you're calling an action called jQueryGetDetailedQuote. If your intention is purely to just GET a result, then perhaps you should use jQuery's $.get() or $.getJSON() functions instead?

How to send a model in jQuery $.ajax() post request to MVC controller method

In doing an auto-refresh using the following code, I assumed that when I do a post, the model will automatically sent to the controller:
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
//data: ??????
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
Every time there is a post, I need to increment the value attribute in the model:
public ActionResult Modelpage(MyModel model)
{
model.value = model.value + 1;
return PartialView("ModelPartialView", this.ViewData);
}
But the model is not passed to the controller when the page is posted with jQuery AJAX request. How can I send the model in the AJAX request?
The simple answer (in MVC 3 onwards, maybe even 2) is you don't have to do anything special.
As long as your JSON parameters match the model, MVC is smart enough to construct a new object from the parameters you give it. The parameters that aren't there are just defaulted.
For example, the Javascript:
var values =
{
"Name": "Chris",
"Color": "Green"
}
$.post("#Url.Action("Update")",values,function(data)
{
// do stuff;
});
The model:
public class UserModel
{
public string Name { get;set; }
public string Color { get;set; }
public IEnumerable<string> Contacts { get;set; }
}
The controller:
public ActionResult Update(UserModel model)
{
// do something with the model
return Json(new { success = true });
}
If you need to send the FULL model to the controller, you first need the model to be available to your javascript code.
In our app, we do this with an extension method:
public static class JsonExtensions
{
public static string ToJson(this Object obj)
{
return new JavaScriptSerializer().Serialize(obj);
}
}
On the view, we use it to render the model:
<script type="javascript">
var model = <%= Model.ToJson() %>
</script>
You can then pass the model variable into your $.ajax call.
I have an MVC page that submits JSON of selected values from a group of radio buttons.
I use:
var dataArray = $.makeArray($("input[type=radio]").serializeArray());
To make an array of their names and values. Then I convert it to JSON with:
var json = $.toJSON(dataArray)
and then post it with jQuery's ajax() to the MVC controller
$.ajax({
url: "/Rounding.aspx/Round/" + $("#OfferId").val(),
type: 'POST',
dataType: 'html',
data: json,
contentType: 'application/json; charset=utf-8',
beforeSend: doSubmitBeforeSend,
complete: doSubmitComplete,
success: doSubmitSuccess});
Which sends the data across as native JSON data.
You can then capture the response stream and de-serialize it into the native C#/VB.net object and manipulate it in your controller.
To automate this process in a lovely, low maintenance way, I advise reading this entry that spells out most of native, automatic JSON de-serialization quite well.
Match your JSON object to match your model and the linked process below should automatically deserialize the data into your controller. It's works wonderfully for me.
Article on MVC JSON deserialization
This can be done by building a javascript object to match your mvc model. The names of the javascript properties have to match exactly to the mvc model or else the autobind won't happen on the post. Once you have your model on the server side you can then manipulate it and store the data to the database.
I am achieving this either by a double click event on a grid row or click event on a button of some sort.
#model TestProject.Models.TestModel
<script>
function testButton_Click(){
var javaModel ={
ModelId: '#Model.TestId',
CreatedDate: '#Model.CreatedDate.ToShortDateString()',
TestDescription: '#Model.TestDescription',
//Here I am using a Kendo editor and I want to bind the text value to my javascript
//object. This may be different for you depending on what controls you use.
TestStatus: ($('#StatusTextBox'))[0].value,
TestType: '#Model.TestType'
}
//Now I did for some reason have some trouble passing the ENUM id of a Kendo ComboBox
//selected value. This puzzled me due to the conversion to Json object in the Ajax call.
//By parsing the Type to an int this worked.
javaModel.TestType = parseInt(javaModel.TestType);
$.ajax({
//This is where you want to post to.
url:'#Url.Action("TestModelUpdate","TestController")',
async:true,
type:"POST",
contentType: 'application/json',
dataType:"json",
data: JSON.stringify(javaModel)
});
}
</script>
//This is your controller action on the server, and it will autobind your values
//to the newTestModel on post.
[HttpPost]
public ActionResult TestModelUpdate(TestModel newTestModel)
{
TestModel.UpdateTestModel(newTestModel);
return //do some return action;
}
I think you need to explicitly pass the data attribute. One way to do this is to use the
data = $('#your-form-id').serialize();
This post may be helpful.
Post with jquery and ajax
Have a look at the doc here..
Ajax serialize
you can create a variable and send to ajax.
var m = { "Value": #Model.Value }
$.ajax({
url: '<%=Url.Action("ModelPage")%>',
type: "POST",
data: m,
success: function(result) {
$("div#updatePane").html(result);
},
complete: function() {
$('form').onsubmit({ preventDefault: function() { } });
}
});
All of model's field must bo ceated in m.
In ajax call mention-
data:MakeModel(),
use the below function to bind data to model
function MakeModel() {
var MyModel = {};
MyModel.value = $('#input element id').val() or your value;
return JSON.stringify(MyModel);
}
Attach [HttpPost] attribute to your controller action
on POST this data will get available

Resources