AJAX 带来完整的文件而不是数据 - VB.NET

AJAX bring the complete file instead data - VB.NET

提问人:Marina 提问时间:6/2/2023 更新时间:6/30/2023 访问量:77

问:

希望你能帮我解决这个问题。我正在尝试使用 AJAX 和 VB.NET 从服务器端获取 javascript 的列表。我尝试了几件事,但它总是返回完整的文件而不是列表。

我尝试使用 Javascript 和 Jquery AJAX,但总是得到相同的结果。 在简历中: DAL上的连接.vb文件 -> 在演示器上调用 DAL.vb -> 返回到 ASCX。VB 文件代码隐藏。

**My Presenter:**
      Public Function GetMenuFromDB() As String
            ....authorization code
                    valueToSet = _accDAL.GetMenuDetailsByUser(UserID) -> my connection to DB
                End If
                If valueToSet.Count > 0 Then
                    Dim serializer As New JsonSerializerOptions()
                    Dim json As String = Text.Json.JsonSerializer.Serialize(valueToSet)
                    Return json
                End If
      End Function

**My file ascx.vb:**
<WebMethod()>
        Protected Shared Function GetMenuFromDB(sender As Object, e As EventArgs) As String
            Dim presenter As New MenuPresenter()
            Return presenter.GetMenuFromDB() 
        End Function]

**My JS:**
function getMenuByUser() {
    var xhr = new XMLHttpRequest();
    var url = "~/Menu.ascx/GetMenuFromDB"
    xhr.open("GET", url, true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.responseText);
        }
    };
    xhr.send();
}

OR Jquery:
$(document).ready(function () {
    $.ajax({
        type: "GET",
        dataType: "json",
        contentType: "application/json; charset=utf-8",
        url: "~/Menu.ascx/GetMenuFromDB",
        success: function (result) {
            debugger;
            console.log(result);
        },
        error: function (xhr, textStatus, error) {
            console.log(error);
        }
    });
});

但是我在 ascx.vb 上放了一个断点,从不输入。 我更改了不同类型的 URL,但不起作用。 此外,为了以防万一,我尝试将方法移动到指向 aspx 文件而不是 ascx,但它的结果相同。

谢谢。

JavaScript vb.net xmlhttprequest asp.net-ajax

评论


答:

1赞 Albert D. Kallal 6/2/2023 #1

您有几个问题。

整个页面都被返回,这往往发生在ajax调用被搞砸甚至无效时(所以整个网页只是刷新并返回到客户端。因此,当您没有有效的 JavaScript 代码时,就会发生这种情况。

还有几件事:

JavaScript 中使用的路径名与客户端 (JavaScript) 代码的语法和格式不同。

因此,例如,您使用“~/”。不幸的是,这在客户端代码中是无效的。

在几乎所有情况下,要使用的路径名都需要是当前页面,或者相对于当前页面。

所以,如果你的当前页面在测试文件夹内,那么你必须(比如)向下走一个文件夹到根目录。

因此,如果我们的当前页面位于一个名为 Testing 的文件夹中,那么我们将不得不使用它:

 url: "../Menu.ascx/GetMenuFromDB"

因此,“~/”仅适用于由 asp.net 和您的代码处理的服务器端代码(隐藏代码)。

事实上,对于asp:Image控件与非asp:Image控件,存在上述相同的问题!

例如,您不能使用:

       <img src="~/Content/Pictures/dog.png">

但是,如果您使用 asp.net 控件,则上述控件有效。

在大多数情况下,这不是一个大问题,但它通常会成为一个问题,尤其是在使用母版页时。

由于母版页路径通常是根目录,但嵌套在任何文件夹中的几个文件夹中的任何旧页仍然可以经常使用母版页?然后你的路径名可能会被搞砸。

因此,例如,我希望在所有页面中都有一个 JavaScript Toast 消息例程。

因此,在我的母版页中,我有这个:

    <%: Scripts.Render("/Scripts/jquery.toast.min.js") %>
    <%: Styles.Render("~/Scripts/jquery.toast.min.css") %>

请注意,我不仅为上述内容添加了脚本标记引用。(因为我不想要一个乱七八糟的路径名)。

现在,让我们来处理你的 ajax 示例。

首先,在大多数情况下,您不需要序列化类,因为这是默认设置,并且由服务器自动完成。

在许多情况下,如果 Web 方法只在给定页面中使用/调用,那么我将 Web 方法拖放到该给定页面中,因为从那时起,在查看页面标记时,我可以轻松地翻转到代码隐藏,并且我不必四处寻找一些包含 Web 方法的 ascx 页面。

好处是,一般来说,我不必担心 JavaScript 中的路径名问题,因为它在同一页面上,因此无论如何都不需要路径名!

因此,让我们在测试页面上做一个示例,因此不使用 ascx。

因此,请记住以上:

我们不能也不会在 JavaScript 中使用“~/”——不允许使用这样的语法。

任何 Web 方法都会为您自动序列化 - 无需在此处使用 JavaScript 或 NewtonSoft 序列化器。

还有一个似乎总是咬我时间,总是忘记的:检查 RouteConfig.vb 中的 route.config 例程。你会看到/找到这个:

    settings.AutoRedirectMode = RedirectMode.Permanent

将上面的内容更改为:

    settings.AutoRedirectMode = RedirectMode.Off

最后提示:

返回到 Web 方法调用的数据以 MyResult.d 的形式返回

请注意 .d

您的退货数据以“.d”格式返回。这只是一个 .net 的东西。

所以,让我们设置一个简单的页面,在页面上放置一些控件。因此,当我们选择一个下拉列表时,我们将执行 100% 的客户端,没有回发,也没有往返。

因此,对于服务器端与客户端寻址,以下是页面标记:

<head runat="server">

    <title></title>
    <script src="../Scripts/jquery-3.4.1.js"></script>
    <link  href="../Content/bootstrap.css" rel="stylesheet" />
    <script src="../Scripts/bootstrap.js"></script>



</head>
<body>
    <form id="form1" runat="server">
        <div style="padding:35px">


            <h4>Select fighter</h4>
            <asp:DropDownList ID="cboFigher" runat="server" Width="300"
                DataTextField="Fighter"
                DataValueField="ID"
                onchange="mychange(this)"
                >
            </asp:DropDownList>
            <br />
            <br />


        <div class="mybox" style="float:left;border:solid 1px">
            <div style="text-align: center; padding: 2px 10px 12px 10px">
                <h3 id="Fighter" runat="server"></h3>
                <asp:Image ID="Image2" runat="server" 
                    Width="180" Height="120" />
                <h4>Engine</h4>
                <asp:Label ID="EngineLabel" runat="server" Text="" />
                <h4>Description</h4>
                <asp:Label ID="DescLabel" runat="server" width="400px"
                    Text="" style="text-align:left" Font-Size="Large" />
            </div>
        </div>

            <script>

                function mychange(myitem) {
                    // get record from server, update
                    // dom values
                    var iPK = myitem.value
                    $.ajax({
                        type: "POST",
                        url: "FighterOneAJ.aspx/GetFighter",
                        data: JSON.stringify({ PK : iPK}),
                        contentType: "application/json; charset=utf-8",
                        dataType: "json",
                        success: function (rData) {
                            var F = rData.d
                            $('#Image2').attr("src", F.ImagePath)
                            $('#Fighter').text(F.Fighter)
                            $('#EngineLabel').text(F.Engine)
                            $('#DescLabel').text(F.Description)

                        },
                        failure: function (rData) {
                            alert("error " + rData.d);
                        }
                    });

                }

            </script>



        </div>
    </form>

现在是此页面的代码隐藏:

我在后面包含完整的页面代码:

Imports System.Web.Services

Public Class FighterOneAJ
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        If Not IsPostBack Then

            cboFigher.DataSource =
                MyRst("SELECT ID, Fighter FROM Fighters ORDER BY Fighter")
            cboFigher.DataBind()
            cboFigher.Items.Insert(0, New ListItem("Select Fighter", "0"))

        End If

    End Sub


    <WebMethod()>
    Public Shared Function GetFighter(PK As String) As clsFigher

        Dim OneFigher As New clsFigher

        OneFigher.ID = PK
        Return OneFigher


    End Function


    Public Class clsFigher
        Public Fighter As String
        Public Engine As String
        Public Thrust As String
        Public Description As String
        Public ImagePath As String
        Private m_id As Integer

        Public Property ID As Integer
            Get
                Return m_id
            End Get
            Set(value As Integer)
                m_id = value

                Dim cmdSQL As New _
                    SqlCommand("SELECT * FROM Fighters WHERE ID = @ID")

                cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = m_id

                With MyRstP(cmdSQL).Rows(0)
                    Fighter = .Item("Fighter")
                    Engine = .Item("Engine")
                    Thrust = .Item("Thrust")
                    Description = .Item("Description")
                    ImagePath = Replace(.Item("ImagePath"), "~/", "../")

                End With
            End Set
        End Property

    End Class
End Class

上述的效果和结果是这样的:

enter image description here

请注意,在上面,服务器端类的返回。请注意,我不必转换为 JSON,甚至不必序列化我返回到客户端的类。

还要注意,即使你只返回一个字符串,或者如本例所示,返回一个类:你使用 rData.d,“.d”部分是返回值。

所以,我想我本可以在该代码中使用 rData.d.Fighter 例如。

如果你想避免脚本引用的相对路径名,那么我们可以改变它:

    <title></title>
    <script src="../Scripts/jquery-3.4.1.js"></script>
    <link  href="../Content/bootstrap.css" rel="stylesheet" />
    <script src="../Scripts/bootstrap.js"></script>

自:

    <title></title>
    <%: Scripts.Render("~/Scripts/jquery-3.4.1.js") %>
    <%: Styles.Render("~/Content/bootstrap.css") %>
    <%: Scripts.Render("~/Scripts/bootstrap.js.js") %>

所以,总而言之:

不能在客户端 JS 代码中使用“~/”。

您必须更改路由配置.vb中的设置

您必须使用“.d”

您不必序列化类或内容 - 这是自动为您完成的。