Supporting WebForm Postbacks in a Non-WebForms application

This is a little crazy but it does work. I have a mobile application framework to uses a couple legacy ASP.NET controls. I had a need for them to support postbacks. The real problem I have is that I don’t support ViewState, I don’t have a ScriptManager and my pages load via AJAX inside the jQuery Mobile framework.

So, even when ASP.NET recognized these controls needs more, my mobile framework ignores its, so what do to? I added some ASP.NET shims for __doPostBack and WebForm_FireDefaultButton.

<!doctype html>
<html>
<head>
     ...
</head>
<body>
    <form id="Form1" runat="server" action="">
         ...
    </form>
</body>
</html>
var theForm; //stupid .net shim

$(function () {
    try {
        theForm = document.forms['Form1'];
        if (!theForm) {
            theForm = document.Form1;
        }
    } catch (e) {
    } 
});

var __defaultFired = false;
function WebForm_FireDefaultButton(event, target) {
    var __nonMSDOMBrowser = (window.navigator.appName.toLowerCase().indexOf('explorer') == -1);
    if (!__defaultFired && event.keyCode == 13 && !(event.srcElement && (event.srcElement.tagName.toLowerCase() == "textarea"))) {
        var defaultButton;
        if (__nonMSDOMBrowser) {
            defaultButton = document.getElementById(target);
        } else {
            defaultButton = document.all[target];
        }
        if (defaultButton && typeof(defaultButton.click) != "undefined") {
            __defaultFired = true;
            defaultButton.click();
            event.cancelBubble = true;
        if (event.stopPropagation) event.stopPropagation();
            return false;
        }
    }
    return true;
}

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        if (!theForm.__EVENTTARGET) {
            var _eventtarget = '<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />';
            $('.aspNetHidden').append(_eventtarget);
        }
        if (!theForm.__EVENTARGUMENT) {
             var _eventarg = '<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />';

            $('.aspNetHidden').append(_eventarg);
        }
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}

How to set the ASP.NET Form Action with jQuery Mobile AJAX requests that redirect

A major problem I have had with using ASP.NET and jQuery Mobile is that jQuery Mobile turns most requests into an AJAX call. It’s very cool, and it is the crux of the framework, also is what makes it feel like a native app instead of a web page. If you are familiar with ASP.NET and it’s single form tag, you know it’s wants to control everything including the “action” of the form.

I know I know ASP.NET MVC…etc is better for jQuery Mobile, but in this specific case, I am tied to a big giant ASP.NET custom CMS engine.

So, what’s happens when we take ASP.NET out of the loop(ajax request/hijacks)? It’s not pretty and you will get all kinds of Event/ViewState errors, postbacks to the root, no events firing…etc. I played with lots of solutions and this is the one that works for me:

1. Disable ViewState and Event Validation

protected override void OnInit(EventArgs e)
{       
    Page.EnableEventValidation = false;
    Page.EnableViewState = false;
    base.OnInit(e);
}

2. Always set the data-url of the jQuery Mobile page being viewed(this updates the browser url during a redirect)

<div id="Home" data-role="page" data-url="<%= Request.RawUrl %>">
......
</div>

3. When the page inits set the form action with a little jQuery

$(document).bind('pageinit', function (event) {
    var activePage = $(event.target); //<---needed because $mobile.activePage isn't available yet
    $('form').attr("action", activePage.attr("data-url"));
});