Getting JSonResult from ASP's Ajax.ActionLink - asp.net-mvc-3

How do I actually get the JSON from a controller method using Ajax.ActionLink? I tried searching the website, but the closest thing I got was ASP.NET MVC controller actions that return JSON or partial html
And the "best answer" doesn't actually tell you how to get JSON from the SomeActionMethod in the ajax.actionlink.

Personally I don't like the Ajax.* helpers. In ASP.NET MVC < 3 they pollute my HTML with javascript and in ASP.NET MVC 3 they pollute my HTML with HTML 5 data-* attributes which are totally redundant (such as the url of an anchor). Also they don't automatically parse the JSON objects in the success callbacks which is what your question is about.
I use normal Html.* helpers, like this:
#Html.ActionLink(
"click me", // linkText
"SomeAction", // action
"SomeController", // controller
null, // routeValues
new { id = "mylink" } // htmlAttributes
)
which obviously generate normal HTML:
click me
and which I unobtrusively AJAXify in separate javascript files:
$(function() {
$('#mylink').click(function() {
$.post(this.href, function(json) {
// TODO: Do something with the JSON object
// returned the your controller action
alert(json.someProperty);
});
return false;
});
});
Assuming the following controller action:
[HttpPost]
public ActionResult SomeAction()
{
return Json(new { someProperty = "Hello World" });
}
UPDATE:
As requested in the comments section here's how to do it using the Ajax.* helpers (I repeat once again, that's just an illustration of how this could be achieved and absolutely not something I recommend, see my initial answer for my recommended solution):
#Ajax.ActionLink(
"click me",
"SomeAction",
"SomeController",
new AjaxOptions {
HttpMethod = "POST",
OnSuccess = "success"
}
)
and inside the success callback:
function success(data) {
var json = $.parseJSON(data.responseText);
alert(json.someProperty);
}

Related

Redirect to partial view on another controller

I am new in asp.net mvc programming, please be gentle... :)
Please notice that the following views are all PARTIAL views! Methods are called through Ajax and redirect to partial views with lists, forms are posted through Ajax, etc. OK, here we go...
1st controller named AlertsController. One of the methods is ResolveAlert(Guid id) which returns RedirectToAction -> UnresolvedAlerts() which is just a list of unresolved alerts.
2nd contoller named FrontDeskController. One of the methods is CustomerDetails(Guid id) which lists the customer and alerts that he might have.
I want to be able to "Resolve an alert" (thus use the method of the 1st controller) but return to the page that I was before instead of going to the redirected page that the method returns.
I added a second parameter to the ResolveAlert() method which lists a returnUrl string. I manage to send the Url that I want it to redirect to but I get just the partial (not rendered inside the whole page as it should)...
Here's my ResolveAlert method on my AlertsController:
// Resolve Alert POST
[HttpPost]
public async Task<ActionResult> Resolve(AlertModel model, string redirectUrl)
{
await _AlertsService.ResolveAsync(model);
if (!string.IsNullOrWhiteSpace(redirectUrl))
return Redirect(redirectUrl);
return RedirectToAction("Unresolved");
}
...and here is my CustomerDetails() method on my FrontDeskController:
// Display Customer Alerts
public async Task<PartialViewResult> CustomerDetails(AttendanceModel model, Guid id)
{
var customer = await _CustomersService.ReadAsync(id);
ViewData["Customer"] = await _CustomersService.ReadCustomerExtendedAsync(id);
var alerts = await _AlertsService.ReadCustomerAlertsAsync(id);
ViewData["Alerts"] = alerts.Where(x => x.IsResolved == false).ToList();
return PartialView("_CustomerDetails", model);
}
The ResolveAlert() method of the first controller is called in two steps... 1st I call a modal from the CustomerDetails view:
function resolveAlert(alertId, customerId) {
var returnTo = '/FrontDesk/CustomerDetails/' + customerId;
$.ajax({
method: 'GET',
url: '/Alerts/Resolve/' + alertId,
data: {returnUrl : returnTo},
dataType: 'html'
}).then(function (html) {
$('#dialog-container').html(html);
showDialog();
});
}
...then on the modal I have:
#{
var data = Request.Params["returnUrl"];
}
#using (Ajax.BeginForm("Resolve", "Alerts", new { redirectUrl = data}, new AjaxOptions() { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "partial", OnSuccess = "hideDialog" }, new { id = "form", #class = "form-horizontal" }))
{ ..... textbox with some notes that I can post while resolving the alert ..... }
... and (finally) here is the final part at the bottom of my modal:
<script type="text/javascript">
$('#form').validate({
rules: {
AlertNotes: {
required: true
}
},
submitHandler: function (form) {
$.ajax({
url: $(form).attr("action"),
data: $(form).serialize(),
type: $(form).attr("method")
}).then(function (result) {
$("#partial").html(result);
hideDialog();
});
}
});
</script>
I think that in order for the returned partial to get rendered correctly inside its container I should be returning a RedirectToAction from the ResolveAlert() method but the problem is that it belongs on a different controller...
Is it possible to get this working somehow or should I just bite the bullet and forget about having those pages as partials, get rid of the Ajax calls and use normal Url.Action() links?
It was just a Javascript/Ajax bug in my code.... Please disregard the question...
For those wondering, I had 2 forms using the same id. JS died silently allowing the form to be posted normally and not through Ajax. It had me scratching my head for a while now. Too bad that web development tools and VS in particular can't snipe such errors and provide a meaningful hint to assist you in debugging...

MVC3 Razor Ajax.ActionLink won't use POST method

I've got a page that contains multiple links. These links should do an ajax post and callback. However, the link is doing a Get instead of a Post. This causes a 404 error since I do not have an action method to handle a get at the requested URL.
If I remove the HTTPPost attribute from my Action method, the link works, but the call back fails and the Json I return is rendered in a new page.
Here is the code I'm using in my view.
<td id="action-#item.ItemID">#Ajax.ActionLink("Add", "AddToOrder", new { itemID = item.ItemID }, new AjaxOptions { HttpMethod = "POST", OnSuccess = "actionCompleted" }, new { id = "add-" + item.ItemID })</td>
This ends up adding this HTML:
<td id="action-012679"><a data-ajax="true" data-ajax-method="POST" data-ajax-success="actionCompleted" href="/mysite/neworder/AddToOrder?itemID=012679" id="add-012679">Add to Order</a></td>
My Controller has the following Action Method.
[HttpPost]
public JsonResult AddToOrder(string itemID) {
return Json(new { id = itemID, Action = "Added", "Just getting this working"});
}
My callback method that is called on Success looks like this:
<script language="javascript" type="text/javascript">
function actionCompleted(response, status, data) {
alert("We have returned");
}
</script>
If I change the [HTTPPost] attribute on my action method to [HTTPGet] I get an Json error. I can fix this by adding the JsonRequestBehavior.AllowGet to my return value, but this doesn't use the call back function defined on the page and fails.
Any help would be appreciated.
Probably you don't have jquery.unobtrusive-ajax.js script attached to page and link is gracefully degraded to regular anchor.
In order to have this working properly. You need to add references to these scripts on your page:
MicrosoftAjax.js
MicrosoftMvcAjax.js

Ajax.BeginForm with OnComplete always updates page

I have simple ajax form in MVC. In AjaxOptions there is OnComplete set to simple javascript function which does one thing - returns false.
#using (Ajax.BeginForm("Action", "Controller", new AjaxOptions { UpdateTargetId = "DivFormId", HttpMethod = "Post", OnComplete = "preventUpdate" }))
function preventUpdate(xhr) {
return false;
}
The problem is, that page is already updated. E.g. in one case controller returns partial view after postback, in other case it returns some Json object. I want it to update page when partial view is returned, and to show dialog window when json is returned. Unfortunately when json is returned, it clears the page (update it with json) even when OnComplete function returns false as MSDN says: To cancel the page update, return false from the JavaScript function.
How to prevent page update depending on received response?
Thank you!
----- UPDATE -------
So far I found following solution. When I don't specify UpdateTargetId, I can do manually with the response what I want. But it is still not documented behaviour with return false.
Use OnSuccess and get rid of UpdateTargetId. Like this:
#using (Ajax.BeginForm("Action", "Controller", new AjaxOptions { HttpMethod = "Post", OnSuccess = "foo" }))
{
...
}
and then:
function foo(result) {
if (result.SomePropertyThatExistsInYourJsonObject) {
// the server returned a JSON object => show the dialog window here
} else {
// the server returned a partial view => update the DOM:
$('#DivFormId').html(result);
}
}

asp.net mvc-4: What should receive an ajax call

I'm new to ASP.NET MVC(-4).
I want to make an Ajax call from my website using jquery and fill in a div on the page using the returned html. Since it is only a div I do not need a full html page with header and full body and stuff.
What should be on the receiving side?
Should it be a normal view, a partial view, some special type of resource or handler or some other magic?
You can use this With Post and Get operaitons
Script
$.ajax({
url: '#Url.Action("SomeView")',
type: 'GET',
cache: false,
data: { some_id: id},
success: function(result) {
$('#container').html(result);
}
});
Controller
public ActionResult SomeView(int some_id)
{
....
return PartialView();
}
View
<div id="container">
#Html.Partial("SomeViewPartial")
</div>
OR you can use AjaxActionLink
View
#Ajax.ActionLink("text", "action", "controller",
new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "container",
OnSuccess = "onSuccess",
})
Script
function onSuccess(result) {
alert(result.foo);
}
Controller
public ActionResult SomeView(int some_id)
{
return Json(new { foo = "bar" }, JsonRequestBehavior.AllowGet);
}
Also You can use Ajax.ActionLink to update only content page. with using this:
In ~/Views/ViewStart.cshtml:
#{
Layout = Request.IsAjaxRequest() ? null : "~/Views/Shared/_Layout.cshtml";
}
Since it is only a div I do not need a full html page with header and full body and stuff
You want a PartialView
You can return a View which has the Layout property value set to null
public class UserController : Controller
{
public ActionResult GetUserInfo()
{
return View();
}
}
and in GetUserInfo.cshtml
#{
Layout=null;
}
<h2>This is the UserInfo View :)</h2>
And you can call it from any page by using jQuery ajax methods
$("#someDivId").load("#Url.Action("User","GetUserInfo")");
If you want the Same Action method to handle an Ajax call and a Normal GET request call, ( Return the partial view on Ajax, Return normal view on Normal Http GET request), You can use the Request.IsAjax property to determine that.
public ActionResult GetUserInfo()
{
if (Request.IsAjaxRequest)
{
return View("Partial/GetUserInfo.cshtml");
}
return View(); //returns the normal view.
}
Assuming you have the Partial View (view with Layout set to null) is presetnt in Views/YourControllerName/Partial folder

ASP.Net MVC 3.0 Ajax.BeginForm is redirecting to a Page?

In ASP.Net MVC 3.0 i am using a Ajax.Beginform
and hitting a JsonResult
on success of the form i am calling a jQuery Function.
but for some reason my form is redirecting to JsonAction
my View
#using (Ajax.BeginForm("ActionName", "Controller", null, new AjaxOptions
{
HttpMethod = "POST",
OnSuccess = "ShowResult"
}, new { id = "myform" }))
{
// All form Fields
<input type="submit" value="Continue" class="button standard" />
}
My controller
public JsonResult ActionName(FormCollection collection)
{
return Json(new { _status },JsonRequestBehavior.AllowGet);
}
jQuery
<script type="text/javascript">
function ShowResult(data) {
// alert("I am at ShowResult");
if (data.isRedirect) {
window.location.href = json.redirectUrl;
}
}
for some reason, when i click submit.
it runs the JSonResult and redirects the page to host/controller/actionname
I have included my
<script src="#Url.Content("jquery.unobtrusive-ajax.min.js")"></script>
in my layout.cshtml
can any one tell me what could be wrong?
I found the problem. Now i have to find the solution
on submit
I am validating my form
$("#myform").validate({
submitHandler: function (form) {
// my logic goes here....
}});
If i exclude the validation Ajax form works as expected.
But if i validate my form then ajax form is not working as expected
Thanks
when this happens its almost always because your script files aren't loaded
note from:
http://completedevelopment.blogspot.com/2011/02/unobstrusive-javascript-in-mvc-3-helps.html
Set the mentioned flag in the web.config:
Include a reference to the jQuery library ~/Scripts/jquery-1.4.4.js
Include a reference to the library that hooks this magic at ~/Scripts/jquery.unobtrusive-ajax.js
So load up fiddler http://fiddler2.com and see if the scripts are being called and loaded.

Resources