Redirect to action with JsonResult - c#

I have a view. When user clicks on a button in my view, I am trying to get some data from my view without reloading my view through an AJAX POST to display some data.
This is the method in my controller :
[HttpPost]
public JsonResult GetUserTraj()
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
This returns a Json Result. I am trying to implement session now. So if the session has expired, I want user to be redirected to the Login view. In the above case if the session expires Session["UserName"] becomes null and an exception is raised.
[HttpPost]
public JsonResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
else
{
RedirectToAction("Login", "Login");
return Json(null);
}
}
I tried the above code. But it doesn't work. It does not redirect the user to the Login view. I tried return RedirectToAction("Login", "Login");. But that doesn't work since the controller action method cannot return something other than JsonResult. Please help me find a solution for the same.

If you use AJAX to request a page, it's cant redirect in browser.
You should response a status code, and then use javascript to redirect in front, like this
[HttpPost]
public JsonResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
else
{
//RedirectToAction("Login", "Login");
return Json(new {code=1});
}
}
You need write this condition Inside of your Ajax success call to reload login screen,
if(result.code ===1){
window.location = 'yourloginpage.html'
}

You can't redirect user to a new page using ajax. For this you have to send some flag at client side and then need to use that flag to identify that session has been expired.
Following code will help you:
[HttpPost]
public JsonResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList = DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(new { Success = true, Data = userTrajList});
}
else
{
return Json(new { Success = false, Message = "Session Expired"});
}
}
jQuery
$.ajax({
url: "any url",
dataType: '',
contentType: "------",
success: function(response){
if(response.Success){
// do stuff
}else{
window.location.href = "/YourLoginURL.aspx"
}
}
});

Just try it
[HttpPost]
public ActionResult GetUserTraj()
{
if (Session["UserName"] != null)
{
var userTrajList =
DBManager.Instance.GetUserTraj(Session["UserName"].ToString());
return Json(userTrajList);
}
else
{
RedirectToAction("Login", "Login");
return Json(null);
}
}
Edit
also your login action should be return json result, if you wont the page reloading
ActionResult is an abstract class that can have several subtypes.
ActionResult Subtypes
ViewResult - Renders a specifed view to the response stream
PartialViewResult - Renders a specifed partial view to the response stream
EmptyResult - An empty response is returned
RedirectResult - Performs an HTTP redirection to a specifed URL
RedirectToRouteResult - Performs an HTTP redirection to a URL that is determined by the
routing engine, based on given route data
JsonResult - Serializes a given ViewData object to JSON format
JavaScriptResult - Returns a piece of JavaScript code that can be executed on the client
ContentResult - Writes content to the response stream without requiring a view
FileContentResult - Returns a file to the client
FileStreamResult - Returns a file to the client, which is provided by a Stream
FilePathResult - Returns a file to the client

Controller
This is a common function may used as a generic one as you wish
public void logoutJson()
{
Response.StatusCode = (int)HttpStatusCode.BadRequest; //Send Error Status to Ajax call
Response.StatusDescription = Url.Action("Index", "Account"); //Url you want to redirect
}
Script
Just paste this code in the View Pages you want to use it. So it will automatically handle All AJAX calls you wanted.
$(document).ready(function () {
$.ajaxSetup({
'complete': function (xhr, textStatus) {
if (xhr.status!="200") {
window.location.replace(xhr.statusText); //Redirect to URL placed in Response.StatusDescription
}
}
});
});
Example
Just call the function for manually fail the AJAX Request and the script in client side handle to redirect to login page.
public JsonResult TestAction()
{
if (null == Session["EmpId"])
{
logoutJson(); //Just call the function
}
}

Related

ASP.Net Core MVC RedirectToAction is appending controller name in front of returnUrl

I am working on a ASP.Net core, MVC 6 application. I have an AppControler as my initial controller and if a user tries to go to an action that has an [Authorize] attribute, I redirect to my AuthController for the login, passing in the returnUrl for the return. Once authenticated, I use ... return RedirectToAction(returnUrl).
In debug, I can see that the returnUrl string is set to /App/Timesheets. However, in the browser address bar, it has an address of http://localhost:49940/Auth/%2FApp%2FTimeSheets. For some reason it is appending the controller name (Auth) in front of the returnUrl.
Here is my Login action in the AuthController
[HttpPost]
public async Task<ActionResult> Login(LoginViewModel vm, string returnUrl)
{
if (ModelState.IsValid)
{
var signInResult = await _signInManager.PasswordSignInAsync(vm.Username, vm.Password, true, false);
if (signInResult.Succeeded)
{
if (string.IsNullOrWhiteSpace(returnUrl))
{
return RedirectToAction("Timesheets", "App");
}
else
{
return RedirectToAction(returnUrl);
}
}
else
{
ModelState.AddModelError("", "Username or password incorrect");
}
}
return View();
}
I can manually enter http://localhost:49940/App/Timesheets in the browser address bar and get to the correct view. Also, if I add
returnUrl = String.Empty; //Test Only
before the line...
if (string.IsNullOrWhiteSpace(returnUrl))
to cause it to execute the line...
return RedirectToAction("Timesheets", "App");
The redirection works just fine. So it has something to do with passing in a string variable in the "/Controller/Action" format that is the problem.
Any ideas?
When you have a full URL already, you should return a Redirect. Currently you are doing a RedirectToAction which will try to redirect to an action under the current controller (Auth).
if (signInResult.Succeeded)
{
if (string.IsNullOrWhiteSpace(returnUrl))
{
return RedirectToAction("Timesheets", "App");
}
else
{
return Redirect(returnUrl);
}
}
var redirect = RedirectToAction();
redirect.ActionName = "YourAction"; // or can use nameof("") like nameof(YourAction);
redirect.ControllerName= "YourCtrl"; // or can use nameof("") like nameof(YourCtrl);
return redirect;
I guess it just took writing out the problem description for me to see the problem.
I changed...
return RedirectToAction(returnUrl);
to...
return RedirectToAction(WebUtility.UrlEncode(returnUrl));
and now it is working properly.
:/

Redirect after Ajax

I have a mvc project, what I want to do is this:
I am sending an ajax request from my JS script. After processing it I want to redirect to a page with a model.
Now I tried sending a form as the ajax response and submit it like so:
sb.Append("<html>");
sb.AppendFormat(#"<body onload='document.forms[""form""].submit()'>");
sb.AppendFormat("<form name='form' action='{0}' method='post'>", "url..");
sb.AppendFormat("<input type='hidden' name='result' value='{0}'>", val1);
.....
And on the JS:
success: function (result) {
var form = $(result);
$(form).submit();
}
But this way i need to specify each post param, I want to send the entire model object.
How can I do that?
Edit
Full steps:
1.Using an MVC APP.
2.I submit button in my view which redirects the user to my JS code.
3.Js code sends an Ajax request to a MVC page called 'Transaction'.
4.C# code doing some actions and now I need to redirect the usr to a page named EOF with ALOT of post params, thats why I want to pass it as a ViewModel.
As you are using ajax, you could return the URL from your action and have it redirected in javascript:
Controller
public ActionResult Transaction()
{
// Do stuff
return Json(new { success = true, redirecturl = Url.Action("RedirectedAction") });
}
Then add something like this to your success handler in javascript:
Javascript (within your success handler)
success: function (result) {
if (result.success == true)
{
window.location = result.redirecturl;
}
}
You can try this:
public ActionResult YourMethod(string param)
{
//what ever you want to do with reference no
return View("EOF");
// or, if you want to supply a model to EOF:
// return View("EOF", myModel);
}

MVC Jquery POST data, redirect to url from ActionResult

I am currently working with mvc. I have a page with more than one button on, which does complicate things a little. However the button I am using calls a jquery function to post data to the controller. This works as expected and data reaches the action and the action does everything expected except redirect.
The function posts data to the controller, or allows the controller to see the values and build up a url to then redirect to. However the redirect doesnt work, and the function calls a success function as expected. If I put the data return into an alert the code for the page is returned in the alert window not the url.
Here is the code:
<input type="submit" value="Assign" name="Assign" onclick="doRedirect()" />
function doRedirect() {
var action = '#Url.Action("Redirect")';
//alert(action);
var opt = {
type: "POST",
data: {
Team: $('#Team option:selected').val()
},
url: action,
success: RedirectSuccess
};
jQuery.ajax(opt);
}
function RedirectSuccess(data) {
if (data != undefined) {
data;
}
}
public ActionResult Redirect(string Team)
{
var hostName = "http://localhost/test/testpage.aspx?";
var team = "&Team=" + Team;
var filterUrl = Team;
return Redirect(filterUrl);**//this doesnt work**
}
Instead of sending back a redirect result from the action, try sending back the URL you want to redirect to. On the client side, you read the response of the request, and do the redirect by setting window.location.href to the URL you get back from the server.
In your action, you could return the URL as JSON for instance:
return Json(new { url: filterUrl });
And in your success callback, you do this to redirect:
if (data !== undefined && data.url !== undefined) {
window.location.href = data.url;
}
This is what I did instead.
public string Redirect(string Team)
{
var hostName = "http://localhost/test/testpage.aspx?";
var team = "&Team=" + Team;
var filterUrl = hostname + Team;
return filterUrl;
}
function RedirectSuccess(data) {
if (data != undefined) {
window.location = data;
}
}
and on my search success

MVC 3 Forms Authentication User.Identity.Name return false

I've got a running MVC 3 (Razor) application with Forms authentication. I can easily call #User.Identety.Name in a partial view, which will return the name of logged in user. But if I call User.Identety.Name in Controller it return null...
If i try check if (User.Identity.IsAuthenticated) it always return null...
I'm confused now...
On logon, I call logon method, which calls SignIn method where I set authentication cookie, which in theory have to contain all the data I need to get.
What am I Doing Wrong?
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (ModelState.IsValid)
{
if (MembershipService.ValidateUser(model.UserName, model.Password))
{
FormsService.SignIn(model.UserName, true);
if (!String.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
else
{
ModelState.AddModelError("", "Brugernavn eller kodeordet er forkert!");
}
}
// If we got this far, something failed, redisplay form
return View(model);
}
public void SignIn(string userName, bool createPersistentCookie)
{
if (String.IsNullOrEmpty(userName)) throw new ArgumentException("Value cannot be null or empty.", "userName");
FormsAuthentication.SetAuthCookie(userName, true);
}
//Upload method is in an Employee Controller.
public string Upload(HttpPostedFileBase fileData)
{
if (User.Identity.IsAuthenticated)
{
var fileName =
this.Server.MapPath("~/uploads/" + HttpContext.User.Identity.Name + "/" +
System.IO.Path.GetFileName(fileData.FileName));
fileData.SaveAs(fileName);
}
return "ok";
}
UPDATE
Okay looks like i found the problem!
If i call User.Identety.Name in a ActionResult method, it returns user name without problem. but if i call it in Upload method which returns String, it mess up!
<script type="text/javascript">
$(window).load(
function () {
$("#fileuploader").fileUpload({
'uploader': '/Scripts/uploader.swf',
'cancelImg': '/Images/cancel.png',
'buttonText': 'Vælg StykListe CSV Fil',
'script': '#Url.Action("Upload","Solar")',
'folder': '/uploads',
'fileDesc': 'Image Files',
'fileExt': '*.jpg;*.jpeg;*.gif;*.png;*.csv',
'multi': true,
'auto': true
});
}
);
It looks like you are using some client side file upload component. If this component uses Flash, it is quite possible that cookies are not sent with the request. You may take a look at the following blog post which illustrates how you could send the authentication cookie value as parameter and on the server reconstruct the token. And here's a similar story.

How to know if the request is ajax in asp.net in Application_Error()

How to know if the request is ajax in asp.net in Application_Error()
I want to handle app error in Application_Error().If the request is ajax and some exception is thrown,then write the error in log file and return a json data that contains error tips for client .
Else if the request is synchronism and some exception is thrown ,write the error in log file and then redirect to a error page.
but now i cant judge which kind the request is . I want to get "X-Requested-With" from header ,unfortunately keys of headers don't contain "X-Requested-With" key ,why?
Testing for the request header should work. For example:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult AjaxTest()
{
throw new Exception();
}
}
and in Application_Error:
protected void Application_Error()
{
bool isAjaxCall = string.Equals("XMLHttpRequest", Context.Request.Headers["x-requested-with"], StringComparison.OrdinalIgnoreCase);
Context.ClearError();
if (isAjaxCall)
{
Context.Response.ContentType = "application/json";
Context.Response.StatusCode = 200;
Context.Response.Write(
new JavaScriptSerializer().Serialize(
new { error = "some nasty error occured" }
)
);
}
}
and then send some Ajax request:
<script type="text/javascript">
$.get('#Url.Action("AjaxTest", "Home")', function (result) {
if (result.error) {
alert(result.error);
}
});
</script>
You can also wrap the Context.Request (of the type HttpRequest) in a HttpRequestWrapper which contains a method IsAjaxRequest.
bool isAjaxCall = new HttpRequestWrapper(Context.Request).IsAjaxRequest();
it is possible to add custom headers in the client side ajax call. Refer http://forums.asp.net/t/1229399.aspx/1
Try looking for this header value in the server.
You could use this.
private static bool IsAjaxRequest()
{
return HttpContext.Current.Request.Headers["X-Requested-With"] == "XMLHttpRequest";
}

Categories