How can I RedirectToAction within $.ajax callback? - asp.net-mvc

I use $.ajax() to poll an action method every 5 seconds as follows:
$.ajax({
type: 'GET', url: '/MyController/IsReady/1',
dataType: 'json', success: function (xhr_data) {
if (xhr_data.active == 'pending') {
setTimeout(function () { ajaxRequest(); }, 5000);
}
}
});
and the ActionResult action:
public ActionResult IsReady(int id)
{
if(true)
{
return RedirectToAction("AnotherAction");
}
return Json("pending");
}
I had to change the action return type to ActionResult in order to use RedirectToAction (originally it was JsonResult and I was returning Json(new { active = 'active' };), but it looks to have trouble redirecting and rendering the new View from within the $.ajax() success callback. I need to redirect to "AnotherAction" from within this polling ajax postback. Firebug's response is the View from "AnotherAction", but it's not rendering.

You need to consume the result of your ajax request and use that to run javascript to manually update window.location yourself. For example, something like:
// Your ajax callback:
function(result) {
if (result.redirectUrl != null) {
window.location = result.redirectUrl;
}
}
Where "result" is the argument passed to you by jQuery's ajax method after completion of the ajax request. (And to generate the URL itself, use UrlHelper.GenerateUrl, which is an MVC helper that creates URLs based off of actions/controllers/etc.)

I know this is a super old article but after scouring the web this was still the top answer on Google, and I ended up using a different solution. If you want to use a pure RedirectToAction this works as well. The RedirectToAction response contains the complete markup for the view.
C#:
return RedirectToAction("Action", "Controller", new { myRouteValue = foo});
JS:
$.ajax({
type: "POST",
url: "./PostController/PostAction",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json",
complete: function (result) {
if (result.responseText) {
$('body').html(result.responseText);
}
}
});

C# worked well
I just changed the JS because responseText was not working for me:
$.ajax({
type: "POST",
url: posturl,
contentType: false,
processData: false,
async: false,
data: requestjson,
success: function(result) {
if (result) {
$('body').html(result);
}
},
error: function (xhr, status, p3, p4){
var err = "Error " + " " + status + " " + p3 + " " + p4;
if (xhr.responseText && xhr.responseText[0] == "{")
err = JSON.parse(xhr.responseText).Message;
console.log(err);
}
});

You could use the Html.RenderAction helper in a View:
public ActionResult IsReady(int id)
{
if(true)
{
ViewBag.Action = "AnotherAction";
return PartialView("_AjaxRedirect");
}
return Json("pending");
}
And in the "_AjaxRedirect" partial view:
#{
string action = ViewBag.ActionName;
Html.RenderAction(action);
}
Reference:
https://stackoverflow.com/a/49137153/150342

Related

Razor MVC calling Action from JavaScript

I'm trying to call an Action from javascript with Ajax but when i publish the site the request returns me a 302 error
this is the javascript call
$("#buyButton").click(function () {
$.ajax({
type: "POST",
url: "/TessileCart/Buy?offerType=" + '#ViewBag.offerType' + "&requestPath=" + '#ViewBag.requestPath' + "&currency=" + currentCurrency,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: ({
}),
error: function (data) {
},
success: function (data) {
window.location = '/'
}
});
});
and this is the Action server side
public ActionResult Buy(string offerType, string requestPath, string currency)
{
try
{
decimal codStore = Convert.ToDecimal(HttpContext.Session[Global.CodStore]);
string userName = HttpContext.Session[Global.UserName].ToString();
cartRep.CheckOut(codStore, userName, System.Web.HttpContext.Current, currency);
return RedirectToAction("Index", "Home", new { offerType = offerType });
}
catch (Exception ex)
{
Global.log.WriteLog(this.GetType().Name, "Buy", "", ex, Session[Global.UserName].ToString());
return RedirectToAction("Index", "Cart", new { offerType = offerType, requestPath = requestPath, error = Global.ErrorMex });
}
}
can someone explain me how to resolve?
Thanks,
Federico
You are calling a post method, but using the get method way.
the url should stop until /buy
url: "/TessileCart/Buy",
before that build the post parameter, before the $.ajax call:
let senddata = {
offerType: #ViewBag.offerType,
requestPath: #ViewBag.requestType,
currency: currentCurrency
}
the rest of parameter, send it as json as input to data
data: JSON.stringify(senddata),
and last decorated your action with HttpPost
[HttpPost]
public ActionResult Buy(...)

JQuery Ajax Post - Action returns Partial View but does not hit success or displays

I am making a call to a controller action as follows:
$j.ajax({
url: url,
type: "post",
data: JSON.stringify(commentParam),
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (data, status, jqxhr) {
$j('#' + commentsCtrlId + ' ul').prepend(data);
commentField.val('');
},
failure: function () {
alert("Error adding comment");
}
});
Where the Action looks like:
[HttpPost]
public ActionResult Create(string commentBody, int parentObjectId, string parentObjectType, int actionId = 0)
{
try
{
// code to check security and pass info to the database. A comment model object is then passed back to the partial view
return PartialView("_Comment", comment);
}
catch (Exception ex)
{
Logger.Instance.LogError("Error in CommentController Create", ex);
return View("Error");
}
}
I can break on this method and the data is passed to the database okay.
I can break point on the Partial View so can see the data is being passed there okay, however when I get back to my ajax call, it never gets a response (neither Success or Failure)! I am not getting any errors any where and absolutely nothing to go on. Does anyone have advice on how I can at least try and debug what is going on here please?
Your method returns a view (html), so you need to change the dataType option to 'html'
$j.ajax({
url: url,
type: "post",
data: JSON.stringify(commentParam),
dataType: 'html', // modify
contentType: "application/json; charset=utf-8",
success: function (data, status, jqxhr) {
Note also your method should return a PartialView in the catch block (as you did for the try block)
catch (Exception ex)
{
Logger.Instance.LogError("Error in CommentController Create", ex);
return PartialView("Error"); // modify
}

How to send json object to the Controller Action method in MVC 4

I am trying to send my userid and password to my login Controller Action method.
//Login button click code
$("#btnLogin").click(function () {
var userCrdential = {
UserName: $("inputEmail3").val(),
Password: $("inputPassword3").val()
};
$.ajax({
type: "POST",
url: "/Home/Login",
content: "application/json; charset=utf-8",
dataType: "json",
data: userCrdential,
success: function (res) {
// alert("data is posted successfully");
if (res.success == true)
alert("data is posted successfully");
else {
// alert("Something went wrong. Please retry!");
}
},
error: function (xhr, textStatus, errorThrown) {
alert(xhr.statusMessage);
}
});
});
and in my home Controller I have login Action method
[HttpPost]
[ActionName("Login")]
public ActionResult Login(User userCrdential)
{
string userIdtest = userCrdential.UserName;
string userPasswordtest = userCrdential.Password;
var result=false;
if (userIdtest != null && userPasswordtest != null)
{
result = true;
}
else
{
result = false;
}
return Json(result);
//return RedirectToAction("Index");
}
but my action method is not invoking...
You need to change content to contentType and call JSON.stringify on your data:
$.ajax({
type: "POST",
url: "/Home/Login",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(userCrdential),
...
});
See jQuery.ajax
Just change it from:
var userCrdential = {
UserName: $("inputEmail3").val(),
Password: $("inputPassword3").val()
};
to:
var userCrdential = "UserName=" + $("inputEmail3").val() + "&Password=" + $("inputPassword3").val();
all other things is ok in your code, but make sure your controller parameter having the same parameters passing here i.e. UserName and Password.
however you need to check user input before calling ajax.
You should never hard-code URLs in MVC.
Instead use #Url.Action.
url: ('#Url.Action("Login", "Home")',
userCrdential needs to be JSON encoded:
JSON.stringify(userCrdential)
Also, for the same of your sanity, please use the fail method.
$.ajax("url")
.done(function() {
alert("success");
})
.fail(function() {
alert("error");
})
One last note, success is deprecated as of jQuery 1.8; you should use done instead.

jquery ajax load partial view to div tag MVC

I've been searching around with no luck on how to make a jquery call to load a partial view in a div tag on my Index view. Some how I am not getting the partial view to update when I click on a link on my tree. The partial view loads when I first run it b/c I call <div id="divid">
#Html.Partial("_InnerView")</div>. After that nothing happens when I click on the link. Or maybe I am not getting the full picture here. Some mentioned to use $('#divid').load = data; or $('#divid').innerHTML= data; but nothing works for me. This is what I have.
Controller:
public ActionResult Test(string parentEls)
{
if (Request.IsAjaxRequest())
{
Employee employee = new Employee();
employee.Name = parentEls + "1";
return PartialView("_InnerView", employee);
}
return View("_InnerView");
}
Index view:
<div id="divid">
#Html.Partial("_InnerView")</div>
$('#tree a').click(function () {
var parentEls = $(this).parents('ul').map(function () {
return $(this).find('a').first().text();
}).get().join(", ");
$.ajax({
type: 'POST',
url: '#Url.Content("~/Home/Test")',
data: {
parentEls: parentEls
},
success: function(data) {
$('#divid').innerHTML = data;
}
});
});
_InnerView.cshtml:
#model TreeDemo.Models.Employee
EmpName:#Model.Name
UPDATE: I got this to work with this
$.ajax({ url: '/Home/Test/', contentType: 'application/html; charset=utf-8', type: 'GET', dataType: 'html', data: { parentEls: parentEls } })
You have to use
$('#divid').html(data);
instead of
$('#divid').innerHTML = data;
Load Partial View in a div MVC 4
Recently I want load Partal View in Div , after doing lots of R&D and It's work for me
$.ajax({
type: 'POST',
url: '#Url.Content("~/ControllerName/ActionName")',
data: {
title: title
},
success: function(result) {
$('#divid').innerHTML = result;
}
});
And In Partal View Action Controller Code
public PartialViewResult ShowCategoryForm(string title)
{
Model model = new Model();
model.Title = title;
return PartialView("~/Views/ControllerName/PartalView.cshtml", model);
}
I think it can be useful if you check the request/response objects of your call, so you can see what is really happening after you make the call... As per your code, I can notice that you're posting using
$.ajax({
type: 'POST',
url: '#Url.Content("~/Home/Test")',
data: {
parentEls: parentEls
},
success: function(data) {
$('#divid').innerHTML = data;
}
});
but your action is marked for 'getting'... you'd need to have something like this
[HttpPost]
public ActionResult Test(string parentEls)
so MVC can understand that the action should be called when HttpPost verb is used

jQuery Ajax call to controller

I'm new to Ajax and I'm trying to disable a checkbox if certain items are selected in a dropdown. I need to pass in the mlaId to the GetMlaDeliveryType(int Id) method in the RecipientsController.cs.
I'm not exactly sure how to set up the ajax call in the javascript function checkMlaDeliveryType(mlaId).
// MLA Add disable express checkbox if delivery type is electronic
$('.AddSelectedMla').change(function () {
var deliveryType = checkMlaDeliveryType($('.AddSelectedMla').val());
// disable express option if delivery type is Electronic
if (deliveryType == "Mail") {
$(".mlaExpressIndicator").removeAttr("disabled");
}else{
$(".mlaExpressIndicator").attr('checked', false).attr("disabled", true);
}
})
// ajax call to get delivery type - "Mail" or "Electronic"
function checkMlaDeliveryType(mlaId)
{
$.ajax({
type: "GET",
url: "/Recipients/GetMlaDeliveryType/" ,
data: mlaId,
dataType: ,
success:
});
}
RecipientsController.cs
public string GetMlaDeliveryType(int Id)
{
var recipientOrchestrator = new RecipientsOrchestrator();
// Returns string "Electronic" or "Mail"
return recipientOrchestrator.GetMlaDeliveryTypeById(Id);
}
EDIT:
Here's how the final javascript looked that worked
// MLA Add disable express checkbox if delivery type is electronic
$('.AddSelectedMla').change(function () {
checkMlaDeliveryType($('.AddSelectedMla').val());
})
// ajax call to get delivery type - "Mail" or "Electronic"
function checkMlaDeliveryType(mlaId)
{
$.ajax({
type: 'GET',
url: '#Url.Action("GetMlaDeliveryType", "Recipients")',
data: { id: mlaId },
cache: false,
success: function (result) {
// disable express option if delivery type is Electronic
if (result == "Mail") {
$(".mlaExpressIndicator").removeAttr("disabled");
} else {
$(".mlaExpressIndicator").attr('checked', false).attr("disabled", true);
}
}
});
}
$.ajax({
type: 'GET',
url: '/Recipients/GetMlaDeliveryType',
data: { id: mlaId },
cache: false,
success: function(result) {
}
});
then fix your controller action so that it returns an ActionResult, not a string. JSON would be appropriate in your case:
public string GetMlaDeliveryType(int Id)
{
var recipientOrchestrator = new RecipientsOrchestrator();
// Returns string "Electronic" or "Mail"
return Json(
recipientOrchestrator.GetMlaDeliveryTypeById(Id),
JsonRequestBehavior.AllowGet
);
}
Now your success callback will directly be passed a javascript instance of your model. You don't need to specify any dataType parameters:
success: function(result) {
// TODO: use the result here to do whatever you need to do
}
Set data in the Ajax call so that its key matches the parameter on the controller (that is, Id):
data: { Id: mlaId },
Note also that it's a better practice to use #Url.Action(actionName, controllerName) to get an Action URL:
url: '#Url.Action("GetMlaDeliveryType", "Recipients")'

Resources