RedirectToAction not working with $.post - c#

I have a problem. I'm trying to redirect my application using a controller method, like this:
[HttpPost]
public ActionResult GetSelected(string Selected, string NewRoleID)
{
var StringSelected = Selected.Split(',');
for (var i = 0; i < StringSelected.Count(); i++)
{
if (StringSelected[i] == "true")
{
R_ROLEMENU newMenu = new R_ROLEMENU();
newMenu.RoleID = int.Parse(NewRoleID);
newMenu.MenuID = i + 1;
var existing = (from item in db.RoleMenus
where (item.RoleID == newMenu.RoleID && item.MenuID == newMenu.MenuID)
select item).ToArray();
if (existing.Count() == 0)
{
db.RoleMenus.Add(newMenu);
db.SaveChanges();
}
}
else
{
R_ROLEMENU oldMenu = new R_ROLEMENU();
oldMenu.RoleID = int.Parse(NewRoleID);
oldMenu.MenuID = i + 1;
var existing = (from item in db.RoleMenus
where (item.RoleID == oldMenu.RoleID && item.MenuID == oldMenu.MenuID)
select item).ToArray();
if (existing.Count() != 0)
{
db.RoleMenus.Remove(existing[0]);
db.SaveChanges();
}
}
}
return RedirectToAction("Logout", "Home");
}
And I'm calling the method with jquery, like this:
$.post("/m_menu/getselected?selected=" + selectedmenus + "&newroleid=" + roleid, function () {
//todo
});
The problem is, the application keeps redirected to index page instead of the Logout action in Home Controller. What am I doing wrong? The rest of the code within the controller is running fine, it's just the redirection that's not working. Please help, thank you

As it is an ajax call RedirectToAction will simply return the action called view as response of post you have to redirect via jquery in $.post call back function:
In Action instead of:
return RedirectToAction("Logout", "Home");
do:
return Content(Url.Action("Logout", "Home"));
and in call back of $.post do this:
$.post("/m_menu/getselected?selected=" + selectedmenus + "&newroleid=" + roleid, function (response) {
window.location = response;
});
or call call javascript at the end of action:
var script = "window.loaction ='"+Url.Action("Logout","Home")+"' ;";
return JavaScript(script);

Related

using methods with href

well i m having 2 hyperlinks :
Fr
|
Ang
in my controller i used this to change the current langage
[HttpPost]
public ActionResult Fr()
{
ContentModelView CMV = new ContentModelView();
//Langue:
int CurrentLanguageid = db.Langues.FirstOrDefault(x => x.active_langue == "true").id_langue;
Langues LangueA = db.Langues.Find(CurrentLanguageid);
LangueA.active_langue = "false";
db.SaveChanges();
int NextLanguage = db.Langues.FirstOrDefault(x => x.txt_langue == "fr").id_langue;
Langues LangueB = db.Langues.Find(CurrentLanguageid);
LangueB.active_langue = "true";
db.SaveChanges();
return (RedirectToAction("../Home/Index"));
}
[HttpPost]
public ActionResult Ang()
{
ContentModelView CMV = new ContentModelView();
//Langue:
int CurrentLanguageid = db.Langues.FirstOrDefault(x => x.active_langue == "true").id_langue;
Langues LangueA = db.Langues.Find(CurrentLanguageid);
LangueA.active_langue = "false";
db.SaveChanges();
int NextLanguage = db.Langues.FirstOrDefault(x => x.txt_langue == "en").id_langue;
Langues LangueB = db.Langues.Find(CurrentLanguageid);
LangueB.active_langue = "true";
db.SaveChanges();
return (RedirectToAction("../Home/Index"));
}
but i don t know if i m obliged to use a parametre in my methode because it s an httpost and it send me to /Home/Fr not the index even after forcing the method no change in database i m struggling with this problem
Clicking on the link element(anchor tag) will issue a GET request.Your action methods are marked with HttpPost and it will not be hit from your GET action request generated by clicking in the link. You have 2 options
Change remove the [HttpPost] decorator from the action method
Hijack the click event on the link and make an http post ajax call.
Also i notice that you have duplicate code in the two methods except the language code you use in your where clause. Why not use a single method with a parameter where you can pass the language code ?
public ActionResult UpdateLanguage(string id)
{
//This is your existing code. I did not verify the correctness of this!
var CMV = new ContentModelView();
//Langue:
int CurrentLanguageid = db.Langues.FirstOrDefault(x => x.active_langue == "true")
.id_langue;
Langues LangueA = db.Langues.Find(CurrentLanguageid);
LangueA.active_langue = "false";
db.SaveChanges();
int NextLanguage = db.Langues.FirstOrDefault(x => x.txt_langue == id).id_langue;
Langues LangueB = db.Langues.Find(CurrentLanguageid);
LangueB.active_langue = "true";
db.SaveChanges();
if(Request.IsAjaxRequest())
return Json(new { status="success"},JsonRequestBehavior.AllowGet);
return RedirectToAction("Index","Home");
}
Now, to make the ajax call, you may simply add a css class to the links
<a class="languageLink" href="#Url.Action("UpdateLanguage", "Home",new {id="fr"})">Fr</a>
<a class="languageLink" href="#Url.Action("UpdateLanguage", "Home",new {id="en"})">En</a>
Now the js code to hijack the link click event and make an ajax call
$(function(){
$("a.languageLink").click(function(){
$.post($(this).attr("href"),function(data){
window.location.href="#Url.Action("Index","Home")";
});
});
});

Stop Execution of HTTPPOST ActionMethod in MVC

I have webApplication in MVC Framework..
i have situation where i have to provide user to export some data to csv file
for that i have written following code ..
[HttpPost]
public ActionResult ExportReportToFile(ReportCriteriaViewModels posdata, string name)
{
string strQuery = GetReportQuery(posdata, name);
IEnumerable<REP_MM_DEMOGRAPHIC_CC> lstDemographics = ReportDataAccess.GetReportData<REP_MM_DEMOGRAPHIC_CC>(strQuery);
if (lstDemographics.Count() > 0)
return new CsvActionResult<REP_MM_DEMOGRAPHIC_CC>(lstDemographics.ToList(), "LISDataExport.csv");
else
return view(posdata);
}
Above code works fine... if in listResult Count is Greater than zero then i returns File to download.. but if i dont get any records in lstDemographics then i returns view..
My problem is when i dont get any result in lstDemographics, i dont want to return view coz it refreshes whole view.. so is there any way where we can stop execution of Action Method and browser doesn't refresh the view and stay as it is..
Thanks..
You will have to make an AJAX call to stop page refresh.
To achieve file export, we actually broke the process in two AJAX calls. First call sends a request to server, server prepare a file and store it in temp table. Server return the file name to AJAX call if there is data. If no data or error, it return a JSON result to indicate a failure.
On success, view make another AJAX request to download the file passing file name.
Something like this:
[Audit(ActionName = "ExportDriverFile")]
public ActionResult ExportDriverFile(int searchId, string exportType, string exportFormat)
{
var user = GetUser();
var driverSearchCriteria = driverSearchCriteriaService.GetDriverSearchCriteria(searchId);
var fileName = exportType + "_" + driverSearchCriteria.SearchType + "_" + User.Identity.Name.Split('#')[0] + "." + exportFormat;
//TempData["ExportBytes_" + fileName] = null;
_searchService.DeleteTempStore(searchId);
var exportBytes = exportService.ExportDriverFileStream(driverSearchCriteria, searchId, exportType, exportFormat, user.DownloadCode, user.OrganizationId);
if (exportBytes != null)
{
var tempStore = new TempStore
{
SearchId = searchId,
FileName = fileName,
ExportFormat = exportFormat,
ExportType = exportType,
DataAsBlob = exportBytes
};
var obj = _searchService.AddTempStore(tempStore);
return Json(fileName);
}
else
{
return Json("failed");
}
}
[HttpGet]
public ActionResult DownloadStream(string fileName, int searchId)
{
var tempStore = _searchService.GetTempStore(searchId);
var bytes = tempStore.DataAsBlob;
if (bytes != null)
{
var stream = new MemoryStream(bytes);
// TempData["ExportBytes_" + fileName] = null;
_searchService.DeleteTempStore(searchId);
return File(stream, "application/vnd.ms-excel", fileName);
}
_logger.Log("Export/DownloadStream request failed", LogCategory.Error);
return Json("Failed");
}
At client side, we do something like:
function ExportData(exportType, exportFormat) {
var searchId = document.getElementById('hfSelectedDriverId').value;
var model = { searchId: searchId, exportType: exportType, exportFormat: exportFormat };
//$('div[class=ajax_overlay]').remove();
//alert("The file will be downloaded in few minutes..");
$.ajax({
url: '#Url.Action("ExportDriverFile", "Export")',
contentType: 'application/json; charset=utf-8',
type: 'POST',
dataType: 'html',
data: JSON.stringify(model)
})
.success(function (result) {
result = result.toString().replace(/"/gi, "");
if (result == "" || result == "failed")
{
alert("File download failed. Please try again!");
}
else
{
window.location = '/Export/DownloadStream?fileName=' + result+"&searchId="+searchId;
}
})
.error(function (xhr, status) {
//
//alert(status);
});
//$('div[class=ajax_overlay]').remove();
}
You should create javascript function with $.getJSON method.
On controller side you just have to check, if you get data from database then return file path else return message.
Your JS code should be something like this:
$.getJSON(url)
.done(function (data) {
if (data.filePath) // If get data, fill filePath
window.location = data.filePath;
else
alert(data.msg);
});
And from controller you can create a HTTPGET Action method that return JSON data like:
return Json(new { msg = "No data found" }, JsonRequestBehavior.AllowGet);
Based on condition you can simple change msg with filePath.

ASP.NET MVC not work with Forms Authentication

I'm trying to use Facebook for users authorization via Forms Authentication in ASP.NET MVC.
I'm getting access token from Facebook and user avatar url and pass these data to Controller, all of this is work just fine until the moment when I need to redirect user.
I did tried FormsAuthentication.RedirectFromLoginPage, RedirectToAction, Response.Redict. None of this methods are working as well as no errors.
Here is the controller:
[HttpPost]
public ActionResult Login(string Url, string AccessToken)
{
string username;
string fullname;
var client = new Facebook.FacebookClient(AccessToken);
dynamic result = client.Get("me", new { fields = "username,first_name,last_name" });
if (result.first_name == null | result.last_name == null)
{
username = result.username;
fullname = null;
}
else
{
username = result.username;
fullname = result.first_name + " " + result.last_name;
}
if (UserExist(username) == false)
{
CreateUser(username, Url, fullname);
//FormsAuthentication.SetAuthCookie(username, true);
//return RedirectToAction("Register", "Home");
FormsAuthentication.RedirectFromLoginPage(username, true);
}
else
{
HttpCookie c = Request.Cookies.Get("UserGuid");
if (c == null)
{
c = new HttpCookie("UserGuid")
{
Value = GetUserGuid(User.Identity.Name),
Expires = DateTime.Now.AddYears(1)
};
Response.Cookies.Add(c);
}
if (result.first_name == null || result.last_name == null)
{
username = result.username;
}
else
{
username = result.first_name + " " + result.last_name;
}
try
{
//FormsAuthentication.SetAuthCookie(username, true);
//Response.Redirect(FormsAuthentication.DefaultUrl);
FormsAuthentication.RedirectFromLoginPage(username, true);
}
catch (Exception)
{
throw new Exception();
}
}
return View();
}
You can't do a simple redirect when accessing your action method through AJAX. You need to do a redirect in your JS code by providing a response url from your controller action.
You can simply return a redirect url from your controller and do the following in JS:
$.ajax({
url: url,
data: data,
success: function(resp) {
window.location.href = resp.Url;
}
})
And in your controller:
return Json(new {Url = "/Home/Index"});

Calling Json from MVC View

I am not sure what I am doing wrong here.
I have a list where I am creating hyperlinks. I need to point the user to the right page first though so I do a getJson.
I have the following code in my .cshtm file:
$.getJSON('/Home/GetLocType', { "locId": loc.locId },
function(result) {
result = Json.stringify(result);
if(result == '1')
{
$('<li><a id=' + loc.locId + ' href="/DataEntry" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
}
else
{
$('<li><a id=' + loc.locId + ' href="/DataEntry/PForm" rel="external">' + loc.locName + '</a></li>').appendTo("#btnList");
}
});
I have the following code in the controller:
private JsonResult GetLocType(int locId)
{
int locationId = Convert.ToInt32(locId);
var result = db.Locations.Where(a => a.LocID == locationId).Select(a => a.TypeId);
return Json(result);
}
The problem I am facing is that the Json method never gets called.
Your controller method is declared as private - As such it would not be accessible.
Change it to public.
Secondly, you should activate allow get - Details on why this is not set by default see - Why is JsonRequestBehavior needed?
public JsonResult GetLocType(int locId)
{
int locationId = Convert.ToInt32(locId);
var result = db.Locations.Where(a => a.LocID == locationId).Select(a => a.TypeId);
return Json(result, JsonRequestBehavior.AllowGet);
}

404 Error When Accessing URL through AJAX

Not sure why, everything seems formatted fine, but I get the HTTP 404 error when attempting to access a function in my controller. Here's the aspx:
function CheckIfPacked() {
if ($("#OrderNumber").val() != "") {
var url = "/Packing/PackageTracking/CheckIfPacked";
$.ajax({
url: url,
cache: false,
data: "orderNumber=" + $("#OrderNumber").val() + "&actionyes=GetSalesOrder()",
success: function (data) {
var domElement = $(data);
if (data != "") {
$('#MessageDiv').append(domElement);
}
});
}
}
And here's the controller:
public Result CheckIfPacked(string orderNumber) {
var mesEntity = new MESEntities();
var packh = from packhead in mesEntity.Packing_Transaction_Headers
where packhead.Order_No_ == orderNumber
select packhead.Completed_by_Packer;
if (packh.First() == 0)
{
return new Result { Success = true, Message = string.Format("You have not finished packing order {0}, are you sure you want to navigate away from this page?", orderNumber) };
}
else
{
return null;
}
}
I think I've just stared at this too long. Thanks.
your method should be static and you should use webmethod attribute for your function :
[WebMethod]
public static Result CheckIfPacked(string orderNumber) {
var mesEntity = new MESEntities();
var packh = from packhead in mesEntity.Packing_Transaction_Headers
where packhead.Order_No_ == orderNumber
select packhead.Completed_by_Packer;
if (packh.First() == 0)
{
return new Result { Success = true, Message = string.Format("You have not finished packing order {0}, are you sure you want to navigate away from this page?", orderNumber) };
}
else
{
return null;
}
}

Categories