Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC4: After server restart, cannot post ajax internal server error 500

I am building an MVC application. It behaves so weird. If I run it on my development server (visual studio debugging) it runs fine even when I restart my application several times by changing the web.config, but when I hosted it, it behaves so weird.

For the first load, everything is normal. I can load all pages, post via ajax, etc just normal, but after I restart the server using HttpRuntime.UnloadAppDomain(); then everytime I post via ajax, I always get

internal server error 500

I do not know what is happening with the application, but I have suspicion that something is going wrong with the client (user) cache / cookies.

I use [ValidateJsonAntiForgeryToken] attribute to the controller functions that receive the post.

[HttpPost]
[ValidateJsonAntiForgeryToken]
public JsonResult LoadPage(int id, string returnUrl, PageFormViewModel pageForm, string jsonFormModel)

And this is the code that handles the json validation token

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
{
    public void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext == null)
        {
            throw new ArgumentNullException("filterContext");
        }

        var httpContext = filterContext.HttpContext;
        var cookie = httpContext.Request.Cookies[AntiForgeryConfig.CookieName];
        AntiForgery.Validate(cookie != null ? cookie.Value : null, httpContext.Request.Headers["__RequestVerificationToken"]);
    }
}

This is the example how I post it:

var getURL = $('#GetURL').val();
var returnUrl = $('#ReturnUrl').val();
var pageId = $('#PageId').val();
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers['__RequestVerificationToken'] = token;

var thePageForm = pageForm;
var theFormModel = formModel;

$.ajax({
    type: 'POST',
    url: getURL,
    contentType: "application/json; charset=utf-8",
    dataType: 'json',
    async: false,
    headers: headers,
    data: JSON.stringify({ id: pageId, returnUrl: returnUrl, pageForm: thePageForm, jsonFormModel: theFormModel }),
    success: function (model) { //Load the page }
    error: function()
});

I have @Html.AntiForgeryToken() in my view. Actually what is wrong with my application? If the problem is that the user cookie is still being accepted by the system but it is not valid, then how to make the user cookie reset after the application being restarted?

---------------------------

Update

It seems that the code is actually able to pass through the controller action, so there is no problem with the validation token, but when the code reached the line that tried to retrieve data from database, this happens

Message: A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: SQL Network Interfaces, error: 26 - Error Locating Server/Instance Specified)

This is my connection string:

Conn string:Data Source=ip address;Initial Catalog=the database name;Integrated Security=False;User ID=user;Password=the password;MultipleActiveResultSets=True

This is the code that produces error:

PageViewModel model = new PageViewModel();
model.Page = dbPages.Pages.Where(m => m.Id == id).First();

If I run it using Incognito mode, it runs fine. So what is exactly going on with my application?

-------------------

Update 2

After a further debugging, I am sure now that the problem lies in the cookies.

These are the cookies:

  1. .ASPXAUTH
  2. ASP.NET_SessionId

I use "InProc" as my session state, which should be reset after application recycle / restart, which is my aim, but I do not know why after application restart, the cookies are still there.

So what I want is to invalidate the session for all user if the server is restarted.

The solution are either:

  1. Get all the sessions from all users and invalidate it
  2. Logout all logon users at Application_End()

Both solutions are impossible from my research. Please help

like image 463
Alvin Stefanus Avatar asked Dec 20 '16 08:12

Alvin Stefanus


2 Answers

I think, this will help you in setting up an event that is fired every time App pool recyles and then this will help you to expire all the cookies inside that event.

like image 69
Rachit Pandey Avatar answered Oct 12 '22 16:10

Rachit Pandey


The AntiForgeryToken (stored in a hidden field) will change after app restart, so all values used from the previous app session (already loaded in your HTML in the browser) are obsolete. You need to refresh the page after app start to get the new token value, or else all ajax calls will be refused! Also there is a cookie named "__RequestVerificationToken" that is used to store that value, you need to remove that one too if exists.

like image 32
Tha'er M. Al-Ajlouni Avatar answered Oct 12 '22 15:10

Tha'er M. Al-Ajlouni