Search code examples
javascriptc#asp.netajaxasp.net-ajax

Asp.net returning whole page


I've been trying to develop a site which has a login system. As part of that I want to make an AJAX call to the server to handle the login system with the username and password. When I make the call, it goes through well but i recieve the entire web page in return and I don't know why

Ajax call(JS):

function AJAXfunc(username, password) {
    var parameter = JSON.stringify({ "username": username, "password": password })
    $.ajax({
        type: "POST",
        contentType: 'application/json; charset=utf-8',
        url: '/Login?handler=LoginFunc',
        data: parameter,
        dataType: 'json',
        headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },

        success: function (data) {
            onsuccess(data)
        },
        error: function (data, success, error) {
            alert("Error: " + error + " - " + data + " - " + success + " - " + data.value)
        }
    })
}

Server side code(C#):

public class LoginModel : PageModel
    {
        public async Task<IActionResult> OnPostLoginFuncAsync(HttpContext http, JsonDocument json)
        {
            return new JsonResult("success");
        }
        
    }

Any help would be much appreciated Thanks

Edit: here is the code that calls the ajax function

function onLoginLoad() {
    const formLogin = document.getElementById("login");
    

    formLogin.addEventListener("submit", function (event) {
        const userName = formLogin.getElementsByClassName("username")[0].value;
        const password = formLogin.getElementsByClassName("password")[0].value;
        // stop form submission
        event.preventDefault();

        AJAXfunc(userName,password);
    });
}

here is the HTML code

<form id = "login"  action = "/LoginFunc" method = "post">
                    <h1>Login</h1>
                    <small></small>
                    <div class = "field">
                    <label for = "username" class="loginpg" style="top:45%;left:45%;position:fixed;color:white; width:10%;">Username</label>
                    <input type="text" class="username" name="username" id="username" style="top:48%;left:45%;position:fixed;width:10%;" placeholder = "Username"><br><br>
                    </div>
                    <div class = "field">
                    <label for = "password" class="loginpg"  style="top:51%;left:45%;position:fixed;color:white;width:10%;">Password</label>
                    <input type= "password" class="password" id="password" name="password"style="top:54%;left:45%;position:fixed;width:10%;" placeholder = "Password"><br><br>
                    </div>
                    <input type="submit" value="Submit" class = "loginpg" style="top:57%;left:45%;position:fixed;width:10%;">
</form>

This is the exact error: 'Unexpected token '<', "\r\n\r\n<!DOCTYPE "... is not valid JSON'


Solution

  • Yes, as a general rule if you client-side JS code is a big pile of a mess?

    Then hitting the web page will OFTEN just choke, and simple return the whole page. When this occurs, it means your code is all wrong.

    When you build/make an AJAX call, you can pass values in the URL. This is what we call a REST call.

    However, in most cases, we all "very much dislike" having to use those messy URL parameters, so when we use .ajax calls, we prefer to use the .data option of the jQuery .ajax call.

    Your code looks to have BOTH - and that's not going to work.

    Next up:

    Remember those .ajax calls are NOT a post-back, and that means in code behind for that page class, such code does NOT have use of an "instance" of the page class (that code for example can't see/use/enjoy/change controls on the page).

    That "method" of the page class MUST be static - since no "instance" of the page class will exist (since there is no page post-back).

    Dump the parameters in the URL - use ONE or the other (data, or URL based parameters).

    Next up, if you NOT creating a separate asmx page with page methods, then if you choose to place the web methods in the existing page? (and I much like this choice, since then code and web methods are in the same place?

    Then that web method must be MARKED as a web method, and also must be a static member of that page.

    So, your code would/should look like this:

    So, say client-side markup and JS code:

        <h3>Enter user</h3>
        <asp:TextBox ID="txtUser" runat="server" ClientIDMode="Static">
        </asp:TextBox>
    
        <h3>Enter password</h3>
        <asp:TextBox ID="txtPass" runat="server" ClientIDMode="Static">
        </asp:TextBox>
    
        <br />
        <asp:Button ID="cmdLogIn" runat="server" Text="Login"
            OnClientClick="mylogin();return false;"                
            />
    
        <script>
    
            function mylogin() {
    
                sUser = $('#txtUser').val()
                sPass = $('#txtPass').val()
                AJAXfunc(sUser,sPass)
    
    
            }
    
    function AJAXfunc(username, password) {
    
        var parameter = JSON.stringify({ "username": username, "password": password })
        $.ajax({
            type: "POST",
            contentType: 'application/json; charset=utf-8',
            url: 'WebCalltest.aspx/LoginFunc',
            data: parameter,
            dataType: 'json',
    
            success: function (mydatastuff) {
                alert('return value = ' + mydatastuff.d)
                // onsuccess(mydatastuff.d)
            },
            error: function (data, success, error) {
                alert("Error: " + error + " - " + data + " - " + success + " - " + data.value)
            }
        })
    }
        </script>
    

    And code behind (assuming same page), then is this:

    [WebMethod]
    public static string LoginFunc(string username, string password) 
    {
        // do whatever
    
        return "this is the string return result";
    }
    

    So, now when we run above, we get/see this:

    enter image description here

    So, above is the "basic" layout and "pattern" as to how this works.

    Now in above example, the web method in the page is on/placed in the same page - hence the URL change I used in above. You of course will have to change the URL to your current page. And be careful, the page URL is relative to your current page - the "/" does not mean root in JS code.

    Also note close, the return value is a .d attribute. This is a .net quirk, and thus you don't use data, but use data.d, or in my example mydatastuff.d

    So, don't forget/leave out the .d to get the return result from that web method.