8

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.

ViVi
  • 4,339
  • 8
  • 29
  • 52
  • 1
    Change the return type to `ActionResult` - but make sure *users* of your method properly handle a redirect result. – Rob Nov 22 '16 at 05:21
  • You can not redirect to action if your action's return type is JsonResult. Change it to ActionResult and in else part just write return RedirectToAction("LogIn","LogIn"); – Jaimin Dave Nov 22 '16 at 05:31
  • Actually I need a `JsonResult` and not `ActionResult` in the normal scenario. If the session is expired, I need `ActionResult`. @Rob & @JaiminDave – ViVi Nov 22 '16 at 05:31
  • @ViVi That use case doesn't really make sense. Either you return JSON, or you return a server response with headers set to redirect. The caller needs to be able to act on both. You typically don't want to redirect if you're returning JSON. You'd return a JSON object indicating the user of the API needs to authenticate. – Rob Nov 22 '16 at 05:32
  • Please move redirect action to the client side, that always checks for Session id in ajax and redirect to login view. – Janaka Dissanayake Nov 22 '16 at 05:33
  • Why you need return type must be JsonResult? since JsonResult inherits ActionResult, you can pass json/action anything you want if your return type is ActionResult – Jaimin Dave Nov 22 '16 at 05:33
  • @JaiminDave : So the answer posted by Ramesh below is the workaround for my issue? – ViVi Nov 22 '16 at 05:36
  • @JanakaDissanayake : Thanks. I will look at it. – ViVi Nov 22 '16 at 05:37
  • 2
    Yes. it works fine. just add JsonRequestBehavior.AllowGet property in return json if necessary. if an action return different types of results you should use ActionResult. – Jaimin Dave Nov 22 '16 at 05:37
  • @Rob : Ok. Got it now. I think I should return Json(null) and do the redirection in javascript, right? – ViVi Nov 22 '16 at 05:38
  • @JaiminDave : Thanks. I will give it a try. – ViVi Nov 22 '16 at 05:39
  • @JaiminDave : The solution provided by **Ramesh Rajendran** is not working. I think I need to redirect from javascript after getting the response itself. – ViVi Nov 22 '16 at 05:46
  • 1
    @ViVi. what i was trying to say that if an action return different types of results you should use ActionResult. you obviously can not redirect to other page if you are using AJAX. you can only do it after getting response. – Jaimin Dave Nov 22 '16 at 06:01

4 Answers4

9

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'
}
Rwing
  • 490
  • 4
  • 19
4

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"
    }
  }
});
Ankush Jain
  • 5,654
  • 4
  • 32
  • 57
2

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

Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
0

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 
          }
    }
MITHUN M
  • 1
  • 3