无效的回发或回调参数 ASP.NET

问题描述 投票:0回答:1

我尝试传递这个movieID并导航到编辑页面(包括删除),但是当我单击按钮时,发生了这种情况。

Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%@ Page EnableEventValidation="true" %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

我无法执行此操作,因为我需要确保页面安全

<%@ Page EnableEventValidation="false" %>

这是我的代码

        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="movieID" HorizontalAlign="Center" OnRowCommand="GridView1_RowCommand">
            <Columns>
                <asp:BoundField DataField="movieID" HeaderText="ID" SortExpression="movieID" ReadOnly="True" />

                <asp:TemplateField HeaderText="Actions">
                    <ItemTemplate>
                        <div class="text-center">
                            <asp:Button ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" CommandArgument='<%#Eval("movieID") %>' Text="Edit"/>
                           <asp:Button ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" CommandArgument='<%#Eval("movieID") %>' Text="Delete"/>
                        </div>  
                    </ItemTemplate>
                </asp:TemplateField>
            </Columns>
        </asp:GridView>
 protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
 {
     int movieID = Convert.ToInt32(e.CommandArgument);

     if (e.CommandName == "Edit")
     {
         // Redirect to edit page
         Response.Redirect("edit.aspx?movieID=" + movieID);
     }
     else if (e.CommandName == "Delete")
     {
         // Redirect to manager page
         Response.Redirect("delete.aspx?movieID=" + movieID);
     }
 }
asp.net gridview callback postback
1个回答
0
投票

好吧,不清楚为什么你想要(或需要)CausesValidation =“false”。

而且,我会考虑转储 gridview 的 Rowcommand (它们不太好用)。只需使用一个标准的、老式的常规 asp.net 按钮和一个按钮单击事件即可。你不再需要任何东西了。

此外,出于安全原因,无需显示、包含或显示 movieID。这个“id”对于最终用户来说几乎没有意义。出于安全原因,公开此类数据库“id”意味着用户可以轻松更改该 id,这是一个安全问题。

那么,说出这个 GridView 标记:

    <asp:GridView ID="GVHotels" runat="server" AutoGenerateColumns="False"
        DataKeyNames="ID" CssClass="table table-hover"
        Width="45%">
        <Columns>
            <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
            <asp:BoundField DataField="LastName" HeaderText="LastName" />
            <asp:BoundField DataField="City" HeaderText="City" />
            <asp:BoundField DataField="HotelName" HeaderText="HotelName" />
            <asp:BoundField DataField="Description" HeaderText="Description" />
            <asp:TemplateField HeaderText="Edit"
                ItemStyle-HorizontalAlign="Center"
                HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="120px">
                <ItemTemplate>

                    <asp:Button ID="cmdEdit" runat="server" 
                        Text="Edit"
                        CssClass="btn"
                        OnClick="cmdEdit_Click"
                        />

                    <asp:Button ID="cmdDelete" runat="server" 
                        Text="Delee"
                        CssClass="btn"
                        OnClick="cmdDelete_Click"
                        style="margin-left:5px"
                        />

                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

注意我们是如何添加 2 个按钮的。请注意我们如何不在标记中显示、公开甚至不包含数据库 PK id。

背后的代码是这样的:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
            LoadGrid();
    }

    void LoadGrid()
    {
        string strSQL =
            "SELECT * FROM tblHotelsA ORDER BY HotelName";

        GVHotels.DataSource = General.MyRst(strSQL);
        GVHotels.DataBind();
    }

    protected void cmdEdit_Click(object sender, EventArgs e)
    {
        Button cmd = (Button)sender;
        GridViewRow gRow = (GridViewRow)cmd.NamingContainer;
        int PK = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];

        Response.Redirect($"edit.aspx?movieID={PK}");

    }

    protected void cmdDelete_Click(object sender, EventArgs e)
    {
        Button cmd = (Button)sender;
        GridViewRow gRow = (GridViewRow)cmd.NamingContainer;
        int PK = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];

        Response.Redirect($"delete.aspx?movieID={PK}");

    }

因此,上面的好处是我们享受了一个简单的按钮单击事件,并且对于添加到 GridView 的每个按钮,我们不关心“行命令”,而且我们也不必显示或在标记中公开数据库 PK id。

事实上,我非常厌恶使用 URL 所谓的查询参数,因为它使 URL 看起来很难看,而且用户可以轻松地更改 URL 中的“id”值。

因此,我会使用会话将值传递到下一页。

因此:

    protected void cmdEdit_Click(object sender, EventArgs e)
    {
        Button cmd = (Button)sender;
        GridViewRow gRow = (GridViewRow)cmd.NamingContainer;
        int PK = (int)GVHotels.DataKeys[gRow.RowIndex]["ID"];
        Session["MovieID"] = PK;
        Response.Redirect($"edit.aspx");

    }

然后在目标页面的页面加载事件中,我可以像这样获取PK数据库值:

        int moiveid = (int)Session["MovieID"];

        // rest of edit or delete code here

所以,我会删除原因valuation = false,这不是必需的。

我将为按钮使用单独的事件存根,您可以使用“命名容器”选取当前的 GridViewRow。命名容器适用于 Repeaters、ListView、GridView 等(适用于所有数据绑定控件)。

因此您不需要在标记中公开 moveid(使用 datakeys 设置)。您不需要将 movieid 传递给按钮单击。而且您也不需要使用 GridView RowCommand。

如果您使用 session[],那么您也不需要在 URL 中包含或显示 movieid。

如前所述,此测试的目标页面是这样的:

        <h3>This is the delete page</h3>

        <h3 id="myheading" runat="server"></h3>

背后的代码:

    protected void Page_Load(object sender, EventArgs e)
    {
        int moiveid = (int)Session["MovieID"];

        myheading.InnerText = $"page to delete moveid = {moiveid}";
    }

因此结果是这样的:

© www.soinside.com 2019 - 2024. All rights reserved.