Search code examples
javascriptc#asp.netpagemethods

Calling C# method (using PageMethod) from LinkButton without postback (MasterPage website)


I create several LinkButtons dynamically in an ASP page with MasterPage. In a separate JavaScript file, i have a JS function that changes the text of the LinkButton when clicked, i.e. "Yes" to "No" and vice-versa. It's sort of a "Like" button. So it's mandatory the page stays static when people click the LinkButton (would be annoying if not). A C# method with parameters must be executed when the LinkButton is clicked.

I add this click property to the LinkButton, to use the method that is in a separate C# Class file:

MyLinkButton.Click += (sender, e) => { MyClass.MyClick(par1, par2); };

But the thing is, if i add the following property to prevent postback and keep the page static when LinkButton is clicked:

MyLinkButton.Attributes.Add("href", "javascript:;");

It no longer runs the MyClick method in the MyClass file.

So i tried to call the MyClick method from the JS code that does the "Yes" to "No" change on click using PageMethod.

In MyClass i added: the reference to System.Web.Services and put [WebMethod] above the public static void MyClick() method. Also added a ScriptManager to my MasterPage file inside body/form and set the attribute EnablePageMethods="true".

The problem is, with or without the ("href", "javascript:;") attribute set on LinkButton, the PageMethod is not calling the MyClick method in the MyClass file. I tried the following two ways:

PageMethods.MyClick(par1, par2)

and

PageMethods.MyClass.MyClick(par1, par2)

And both aren't triggering the method. I appreciate any comments or suggestions.


Solution

  • The way a link button works is, its href points to the __doPostBack JavaScript method. This triggers a message to be sent to the server. Since you've replaced the href with javascript:, essentially "do nothing," that explains the behavior you're seeing.

    If you want to send data to the server without reloading the page, you need to use AJAX. There are two main methods, one is the UpdatePanel, most people, including myself, would recommend against this model. Why? Well think of it this way, based on what you're telling me, you have a "like" button. I'd guess there are two pieces of data your server-side method needs, some ID to identify what they are liking and a Boolean to say like or not like. If you use an UpdatePanel, the entire ViewState has to roundtrip to the server. Additionally, the server will respond with the entire HTML contents of everything in the UpdatePanel. There are many good articles on the internet that go into more detail, here is one if you're interested, but I've summarized the points. If you're trying to build a lightweight, fast modern website, it's not the way to go. If you're trying to get something done quickly and don't want to write JavaScript, it might be, however JavaScript is pretty much a requirement for the modern web.

    Alternatively, you can use straight AJAX. This requires you to put a method in your code behind decorated with the [WebMethod] attribute. This means it can now be called from JavaScript via AJAX. Using my example you'd have:

    [WebMethod]
    public static bool DoLike(string id, bool likeOrNotLike)
    {
        // Your implementation
    }
    

    Now, how do you call it. I'd recommend you use a framework such as jQuery to call the AJAX as it simplifies a lot of the syntax for you. With jQuery, you can simply do:

    $.ajax({
        type: "GET",
        url: "MyPage.aspx/DoLike",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        data: { id: "123", likeOrNotLike: true },
        success: function (msg) {
            alert("It was called successfully");
        },
        error: function () {
            alert("An error occurred calling it");
        }
    });
    

    The code above sends two parameters to the DoLike method, "123" (the ID), and true (likeOrNotLike). You're method will be called with these parameters as if you had called it from C#. The framework takes care of all of that.

    To add jQuery to your page, simply add a:

    <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script>
    

    If you're against jQuery, I can modify my answer to use XMLHTTPRequest directly but it's more cumbersome.

    As you can see, AJAX isn't magic though, you can't simply add [WebMethod] to your event handler and all will work. In fact, if you go the straight AJAX route, you're not even using an event handler, you're calling a server side method directly.

    You can certainly do the UpdatePanel as some others have suggested here, it will work. It's just, in my, and many other opinions, overkill for AJAX. It was Microsoft's attempt at implementing AJAX without the developer having to do much. Just like with ViewState, it comes with a price. It's up to you if the price is tolerable.