Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
First off, I know there will be some who will tell me that this has been answered in a number of places. This appears to be a functional issue with VS 2019.

I have created a VERY basic webpage with a single call to the codebehind with a PageMethods call.

The codebehind method is never called and the "return" value is the current page coding, not what should have been returned ("Hello JC Williams"). I do not see any error messages within Chrome Developer Tools. I have attempted to run this under Chrome, Edge, Opera, and Firefox with the same results.

Below is a link to the image of the page after the button is clicked, as it is rendered in Chrome.

The aspx is:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="TestPage.aspx.cs" Inherits="TestPage" %>  
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
    <html xmlns="http://www.w3.org/1999/xhtml">  
  
    <head runat="server">  
        <title></title>  
        <script type='text/javascript'>  
            function GetName() {  
                PageMethods.Name(Success, Failure);  
            }  
  
            function Success(result) {  
                alert(result);  
            }  
  
            function Failure(error) {  
                alert(error);  
            }  
        </script>  
    </head>  
  
    <body>  
        <form id="form1" runat="server">  
            <asp:ScriptManager ID='ScriptManager1' runat='server' EnablePageMethods='true' />  
            <div>  
                <asp:Button ID="Button1" runat="server" Text="Get Name" OnClientClick='GetName();return false;' /> </div>  
        </form>  
    </body>  
  
    </html>  


The C# code is:

using System;
using System.Web.Services;

public partial class TestPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
    }

    [WebMethod]
    public static string Name()
    {
        string Name = "Hello JC Williams";
        return Name;
    }
}


The "returned" value (from the alert()):

https://emsend.us/images/return.png

I am using VS2019, ASP.NET Web Application (.NET Framework), .NET Framework 4.7.2

What I have tried:

I had code that was working, and now it does not, that is why I embarked on this test.
I have uninstalled and re-installed VS 2019.
I have created a new project and only have this code in that project.
I have attempted to run this on several browsers with the same results.
Do not know what has changed and appears to be something with my system configuration?
Maybe there is something regarding jquery JS code?
Posted
Updated 8-Sep-21 5:31am
v2
Comments
Member 15329613 7-Sep-21 15:23pm    
An easy and better way (in my opinion) is to use jquery's .ajax call.
Jc Williams 2021 7-Sep-21 16:38pm    
I thought that PageMethods IS an AJAX call, but without having to explicitly write all the coding for the call, or am I completely wet here? If there were a better (read easier) way, then why create a method that is unreliable or less easy to code? Besides, more to the question is why am I getting a return of the page instead of the information from the codebehind? Is it possible that the HTTP GET is not firing right and is returning the "default" coding from the calling page?
Member 15329613 8-Sep-21 7:19am    
I did ASP.Net web forms for many years and never used that method nor did I see other developers use it so I am not familiar with it. But jquery is very easy to use. Here is an example:

function Test() {
$.ajax({
type: "POST",
url: "/Home/Method",
success: function (data) {
if (data != "") {
alert(data);
}
else {
DoWhatever();
}
},
error: function (jqXHR, exception, errorThrown) {
alert(jqXHR.responseText);
}
});
}
Jc Williams 2021 7-Sep-21 21:38pm    
I have continued to test and I have found that if I use jquery .ajax call it returns the exact same results. I then put a breakpoint at the Page_Load method in the codebehind and find that either jquery .ajax or PageMethods actually are calling the Page_Load and is receiving the page markup as that would be what is expected from the Page_Load process. Is it possible that somehow the routing tables are either messed up or routing is not properly being handled?
Richard Deeming 8-Sep-21 3:47am    
It sounds like there's a conflict between the URL used to call the page method and your routing config. Can you add your RouteConfig code to the question?

1 solution

After a lot of research and testing, I found this solution:

in App_Start -> RouteConfig.cs, this is the final version, which takes care of part of the issue:

using System.Web.Routing;
using Microsoft.AspNet.FriendlyUrls;

namespace EMSend
{
    public static class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            var settings = new FriendlyUrlSettings();
            settings.AutoRedirectMode = RedirectMode.Off;
//            settings.AutoRedirectMode = RedirectMode.Permanent;
            routes.EnableFriendlyUrls(settings);
        }
    }
}

I changed the RedirectMode to Off, from Permanent. One author suggested that you delete the line: routes.EnableFriendlyUrls(settings);. This actually has the effect of killing all friendly routings. IMHO, you should use any settings (as that is why they exist) over just removing code because it "appears" to solve your issue.

In this case, it was still returning the entire page coding as it was still generating a 401 (access denied) error.

Next, in my .aspx page where I perform the PageMethods, I included setting the path instead of letting the routing try to figure it out.

Right before I call my PageMethods to the CodeBehind, I added the set_path, like this:

PageMethods.set_path('/Default.aspx');
PageMethods.ValidLogin(account, password, onOK, onError);
return false;

I attempted to include the set_path in the global area of my script, but it does not seem to work there. It generated a 404 error when the PageMethods was called. Therefore you will have to set it before you use the PageMethods call.

Here is a tested side note: If you change your path to something else, like:
PageMethods.set_path('/PlaceHolder.aspx');

and you have within Placeholder coding which is used by multiple pages, then you can have only one place to maintain your coding. Think about things like customer creation/maintenance/delete. You can call just one method and just have a flag to determine which function you are going to use within one method. I am an advocate for simple. Have only one place to maintain coding reduces the chances of errors being created because you have multiple places where you need to maintain the same coding.

In the case of something like customer records, having the same backend then allows you to write the UI to accomplish the visual stuff (like allow for record entry vs display information, but do not edit it). Business Rules belongs in the backend and visual representation in the front end (UI).

As a side note: All of you who keep saying "Use jQuery .ajax", what do you think PageMethods is? It is a much simpler interface to your CodeBehind. During my testing, I found that jQuery is actually called and the error (401 which has been fixed with the coding above) was thrown by jQuery, regardless of the method I used to call the backend. The main differences between the two methods are:

1. With .ajax, people forget to specify the data typing, and other settings, and end up frustrated about getting data to their method, or even getting it called. These are automatically set up with the PageMethods call.
2. There appears to be no difference between GET/PUT/POST, when it come to how the method consumes the data, nor the information returned to the call, as all of the parameter data is always passed from the code, not from the body or URI as in a regular api call. You do not have to specify what type of call with PageMethods.
3. The "jQuery .ajax" call is very verbose, and therefore much easier to miscode a setting, parameter variable, or even how to handle the returning function calls. The PageMethods call is simple. Simpler or better ... less chances to screw things up.

After 45 years of programming, the simpler you can make the code, the less chances you can mess up. Just a thought.
 
Share this answer
 
v5

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900