0

Ajax returns masterpage html instead of returns from my method.

Here is my client code:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Page1.aspx.cs" Inherits="Page1"
    MasterPageFile="~/MasterPage.master" EnableEventValidation="false" %>

function saveForm() {
    
    let formData = new FormData();
    formData.append("name", "john");

    $.ajax({
        type: "POST",
        url: 'Page1.aspx?method=SaveForm',
        data: formData,
        contentType: false,
        processData: false,
        cache: false,
        success: onSuccessSaveForm,
        failure: function (response) {
            alert(response.d);
        },
        error: function (response) {
            alert(response.d);
        }
    });
}

Here is my server code:

public partial class Page1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["method"] != string.Empty && Request.QueryString["method"] != null)
        {
            Type thisType = this.GetType();
            MethodInfo theMethod = thisType.GetMethod(Request.QueryString["method"]);
            theMethod.Invoke(this, null);
        }
    }
}

public string SaveForm()
{
    Result result = new Result();
    ...code
    return JsonConvert.SerializeObject(result); -->(*expect to return this)
}

Expectations:

stop at theMethod.Invoke(this, null) and returns to my ajax call

Result:

it continues to page_load method at MasterPage.master.cs, and returns the whole html as result

How to pass result from theMethod.Invoke(this, null) to front end. And if possible, not having to go MasterPage.master.cs too and not involve refreshing the page, like using [System.Web.Services.WebMethod].

4
  • Your way to invoke the method is wrong. By adding [WebMethod] to SaveForm you can call the method directly . You have here a similar answer: stackoverflow.com/questions/19701658/… Commented May 13, 2024 at 8:51
  • @DA hmm, can that method use FormData? when i tried it, adding contentType: false and processData: false will throw illegal invocation in client side. Commented May 13, 2024 at 8:58
  • Just serialize your form data: var $frm = $('#form1'); .... $.ajax({ data: $frm.serialize(),.... And in the method SaveForm deserialize it. Commented May 13, 2024 at 9:02
  • @DA i've tried that. That works except can't use HttpContext.Current.Request. But the reason i'm doing it, is because i want to use HttpContext.Current.Request as i'm uploading files. If it's not possible, then i have to split the process to ashx or turning it to blob and use webmethod. I wanted to combining it first, and using page_load and system reflection can. and doing so teach me so in future i know to call method name dynamically. The problem is, it doesn't return the correct data. Commented May 13, 2024 at 9:24

2 Answers 2

0

I suspect some error is occurring here.

Note that you do need to "clear" the response, else you will receive the whole page back.

Here is some sample working code:

        <input id="Button1" type="button" value="test post"
            onclick="mypost();return false"                
            />


        <script>

            function mypost() {

                var formData = new FormData();
                formData.append("FirstName", "Albert");
                formData.append("LastName", "Albert");

                $.ajax({
                    url: "SimpleUpdate.aspx?method=SaveForm", // Replace with your server endpoint
                    type: "POST",
                    data: formData,
                    contentType: false, // Important: Set to false to prevent jQuery from setting the content type
                    processData: false, // Important: Set to false to prevent jQuery from processing the data
                    success: function (response) {
                        // Handle the server response here
                        alert(response);
                    },
                    error: function (xhr, status, error) {
                        console.error("Error:", error);
                    }
                });

            }


        </script>

And code behind:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.HttpMethod == "POST")
        {

            if (Request.QueryString["method"] != "")
            {
                string sMethod = Request.QueryString["method"];
                Type thisType = this.GetType();
                MethodInfo theMethod = thisType.GetMethod(sMethod);
                theMethod.Invoke(this, null);
            }
        }
    }


    public  void SaveForm()
    {
        Debug.Print("FirstName = " + Request.Form["FirstName"]);
        Debug.Print("LastName = " + Request.Form["LastName"]);
        Response.Clear();
        Response.Write("This is return value");
        Response.End();

    }

So, above does work, but I suggest it better to dispense with all that code in the page load event, and simply call a web method directly.

So, say we wish to grab first and last name from 2 textboxes, and pass to server using a web method (end point).

The server web method will combine into full name, and return this value.

Markup:

        FirstName:
        <asp:TextBox ID="txtFirst" runat="server" ClientIDMode="Static">
        </asp:TextBox>
        LastName:
        <asp:TextBox ID="txtLast" runat="server" ClientIDMode="Static">
        </asp:TextBox>
        <br />


    <input id="cmdSaveName" type="button" value="Save user name"
        onclick="mypost2();return false"                
        />

    <script>

        function mypost2() {

            var sF = $('#txtFirst').val()
            var sL = $('#txtLast').val()

            $.ajax({
                url: "SimpleUpdate.aspx/MySaveName", // Replace with your server endpoint
                type: "POST",
                data: JSON.stringify({ FirstName: sF, LastName: sL }),
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function (response) {
                    // Handle the server response here
                    alert(response.d);
                },
                error: function (xhr, status, error) {
                    console.error("Error:", error);
                }
            });
        }
    </script>

And now code behind:

    [WebMethod]
    public static string MySaveName(string FirstName, string LastName)
    {

        Debug.Print($"First Name ={FirstName}");
        Debug.Print($"LastName Name ={LastName}");

        return $"Full Name = {FirstName + " " + LastName}";
    }

So, note now we don't have to parse out the paramters, and we don't have to parse out the page method and we don't have to use reflection to trigger a method of our choice.

The result is thus this:

enter image description here

Note close that any value(s) returned are found in the ".d" property of the ajax response, and this is just a .net quirk for reasons of security.

So, as you can see, we vast can reduce parsing, and you can tag a code behind routine as a WebMethod. Such methods must be static, and thus that method can't see or grab control values in the code behind, but you are free to pass such values from the client side ajax call.

All in all, I don't see the advantages of bothering with a JavaScript Form object, a .ajax post of that form data, and then using URL Query string + reflection.

And yes, in most cases, using the first example, the whole page is returned, but you can clear the response, and then using Response.Write to control what is returned to the .ajax post.

The page should not go blank, nor appear to experience a post back in both of the above examples.

I not tested using a JavaScript Form object and post with a master page.

However, I often use a web method with master pages, and the web methods can freely be placed in any web page, but not the master page.

Better would be to create a .asmx web end point (web service), and the above ajax code (non form post) example will work much the same.

If such code is to be called and used in the master page, and not the child page?

Then I much suggest you use a .asmx (create a web service).

eg:

enter image description here

Hence, call and use the WebMethod end points in that .asmx page.

Sign up to request clarification or add additional context in comments.

Comments

0

Orait. So basically, all i have to do is write the result to Response and then end it. So the page_load method will be:

public partial class Page1 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (Request.QueryString["method"] != string.Empty && Request.QueryString["method"] != null)
        {
            Type thisType = this.GetType();
            MethodInfo theMethod = thisType.GetMethod(Request.QueryString["method"]);
            string result = theMethod.Invoke(this, null).ToString();

            HttpContext.Current.Response.Write(result);
            HttpContext.Current.Response.Flush();
            HttpContext.Current.Response.SuppressContent = true;
            HttpContext.Current.ApplicationInstance.CompleteRequest();
        }
    }
}

4 Comments

Why then not just use a standard button with its click event? You can then use and grab values from those text boxes, notes etc. And the file upload control will have the file data. Zero Javascript required here. File upload control requires a post back anyway.
@AlbertD.Kallal Is standard button with it's click event mean button type='submit' or like runat='server' onclickserver='BtnSaveForm_CLick'?
I mean to use a standard asp.net button with a click event in place of that jquery .ajax, since in effect by disabling the .ajax processData, and contentType, you are in effect doing a post-back anyway. So, it looks like you can just use a standard server button, and thus grab values from a bunch of standard server controls placed in that page.
Tried on other thing. 2 questions. 1. How to stop the page from fully refresh? 2. My master page and current page gone, and my screen simply shows like empty html with only the result written on it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.