I have an ASP.NET MVC web site with a large number of Ajax calls to different server-side functions. This site requires a login, so it shouldn't be returning any JSON data if the user isn't logged in. I've already set the site up so that if the user attempts to go to any page or file other than the login page, it returns them to the login page. The problem is that it's doing this with the JsonResponse functions as well, returning the code of the login page when a Json object is expected. I need the Ajax function to recognize the "Not Logged In" error so it can initiate the sending the user back to the login page.
A bit of background, the site does all its database retrieval through a WCF webservice. Whenever a user interacts with the database at all, a last_access DateTime field in the users table is updated. If the user tried to access something and the last_access field shows more than X minutes ago, the webservice throws a "Not Logged In" error back at the web server. I have Application_Error sending them back to the login page with a notice when that happens.
I needed a way to differentiate functions that need to return to the login page from functions that need to return an actual error and function attributes seemed like the easiest way.
Here's an example of one of the JsonResult functions
[HttpPost]
[AjaxTimeoutErrorCheck]
public JsonResult GetRecords() {
ExpDataClient client = new ExpDataClient();
string groups = string.Join(",", SearchSettings.GetGroups().Select(g => g.employerId).ToList());
List<ExpDataService.GetEligibilityResult> items = client.GetEligibility(groups);
JsonResult json = Json(items, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
}
I have an attribute object set up to handle exceptions in the relevant functions. If I do the following
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
filterContext.RequestContext.HttpContext.Response.StatusDescription = "No user logged in";
without setting the filterContext.Result, I can get the Ajax function to recognize it as an error, but there is nothing in the return object indicating that it's an error. I suspect that I'm just garbling the response.
I've tried using this https://stackoverflow.com/a/43069917/487909 to create an object to assign to filterContext.Result, but it seems like setting filterContext.Result to anything (other than null, at least) causes the Ajax function to recognize the returned object as valid.
Here's what I currently have for the attribute object
public class AjaxTimeoutErrorCheck : FilterAttribute, IExceptionFilter {
void IExceptionFilter.OnException(ExceptionContext filterContext) {
if (filterContext.Exception.Message == "At least one security token in the message could not be validated.") {
filterContext.ExceptionHandled = true;
var response = new { statusText = "No user logged in" };
filterContext.RequestContext.HttpContext.Response.Status = "401 Unauthorized";
filterContext.RequestContext.HttpContext.Response.StatusCode = 401;
filterContext.RequestContext.HttpContext.Response.StatusDescription = "No user logged in";
filterContext.Result = new Models.JsonHttpStatusResult(response, System.Net.HttpStatusCode.Unauthorized);
};
}
}