Search code examples
javascript.netajaxurl-routingdopostback

AJAX PageMethods conflict with Routing?


EDIT: Latest Info at the bottom of Post.

I've got an Update Panel on a page that I force to postback with __doPostBack.

Everything works fine when I browse it at /path/page.aspx.

However, as soon as I access the page through a route like /otherpath/page the postback does not occur.

Any suggestions?

Here is my JS File:

/// <reference name="MicrosoftAjax.js"/>
function Check() {
   // Call the static page method.
   PageMethods.GetLatestHeadlineTick(OnSucceeded, OnFailed);
}

function OnSucceeded(result, userContext, methodName) {
   // Parse the page method's result and the embedded
   //  hidden value to integers for comparison.
   var LatestTick = parseInt(result);
   var LatestDisplayTick = parseInt($get('LatestDisplayTick').value);

   // If the page method's return value is larger than 
   //  the embedded latest display tick, refresh the panel.
   if (LatestTick > LatestDisplayTick)
    __doPostBack('UpdatePanel1', '');
   // Else, check again in five seconds.
   else
    setTimeout("Check()", 5000);
}

// Stub to make the page method call happy.
function OnFailed(error, userContext, methodName) { }

function pageLoad() {
  // On initial load and partial postbacks, 
  //  check for newer articles in five seconds.
  setTimeout("Check()", 5000);
}

And my Markup:

<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="True">
        <Scripts>
            <asp:ScriptReference Path="/resources/js/bus-times.js" />
        </Scripts>
    </asp:ScriptManager>
    <asp:UpdatePanel ID="UpdatePanel1" runat="server" ClientIDMode="Static">
        <ContentTemplate>
            <asp:GridView ID="gvSchedule" runat="server" AutoGenerateColumns="False" Width="80%">
                <AlternatingRowStyle CssClass="altrowstyle" />
                <HeaderStyle CssClass="headerstyle" />
                <RowStyle CssClass="rowstyle" />
                <Columns>
                    <asp:BoundField DataField="RouteName" HeaderText="Route" />
                    <asp:BoundField DataField="TimeTillDeparture" HeaderText="Departs In" />
                    <asp:BoundField DataField="ScheduledDepartureTime" HeaderText="Est. Departure Time" />
                </Columns>
                <EmptyDataTemplate>
                    Data is currently unavailable.
                </EmptyDataTemplate>
            </asp:GridView>
            <div class="updatedstyle">
                Last updated:
                <asp:Label ID="updated_time" runat="server" ></asp:Label></div>
            <asp:HiddenField runat="server" ID="LatestDisplayTick" ClientIDMode="Static" />
            <asp:HiddenField runat="server" ID="hf_stopID" ClientIDMode="Static" />
        </ContentTemplate>
    </asp:UpdatePanel>

And the Ajax Method in the code-behind:

<WebMethod()> _
Public Shared Function GetLatestHeadlineTick() As Long

    Dim stopID As String
    If HttpContext.Current.Request.QueryString("stop_id") <> Nothing Then
        stopID = HttpContext.Current.Request.QueryString("stop_id")
    Else
        stopID = "678036"
    End If

    ' Retrieve the cached DataTable.
    Dim dt_added As DateTime = CType(BusScheduleService.GetBusDataDateAdded(stopID), DateTime)

    ' Return that bus data timestamp, in ticks.
    Return dt_added.Ticks

End Function

EDIT:

Here is a picture from Fiddler. With the working version at the top and the error at the bottom. It returns a 405 request. So it seems like the Ajax request is being interpreted as an actual route name when it resolves, but that route doesn't exist so it isn't working. How can I get around this? It seems like when Ajax calls a function it does so by designated a /functionName after the URL, but this mimics route syntax...

Fiddler Output

So when the AJAX tries to call the GetLatestHeadLineTick via /path/page.aspx/GetLatestHeadLineTick, it works. But with a route it goes to /otherpath/page/GetLatestHeadLineTick, which I guess my site is trying to handle that as a route and not AJAX request.

I also notice on the request that works, it says the content type is JSON, but on the failed request it's being interpreted as HTML.


Solution

  • Welp, I solved the problem, it took forever to find the actual cause, but routing has no conflict with __doPostBack or AJAX function calls. The problem is there is a conflict between PageMethods class and routing.

    PageMethods.GetLatestHeadlineTick(OnSucceeded, OnFailed);

    The above line looks at the route and tries to get page methods from the route, which doesn't work.

    So all I needed to do was add this line right before that one:

    PageMethods.set_path('/actualpath/actualpage.aspx')

    Works!