【问题标题】:GridView with SqlDataSource: Update does not work带有 SqlDataSource 的 GridView:更新不起作用
【发布时间】:2016-01-08 19:19:50
【问题描述】:

我正在使用 GridView 的自动生成编辑功能。出现编辑按钮,单击它进入编辑模式,但进行更改并单击更新什么都不做(我可以说)。数据库不更新。通过测试似乎 OnRowEditing 触发但 OnRowUpdating 没有。 INSERT、SELECT 和 DELETE 都可以完美运行。我已经直接在 SQL 数据库上测试了我的 UpdateCommand,它按预期工作。

为什么这不起作用?这几天我一直在寻找答案。

这是当前状态下的完整代码:

<%@ Page Language="C# " AutoEventWireup="true"%>
<%@Import Namespace="System.Data" %>
<%@Import Namespace="System.Data.Common" %>
<%@Import Namespace="System.Data.SqlClient" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    private void InsertDomain(Object source, EventArgs e)
    {
        SqlDataSource2.Insert();
    }
    private void OnDomainDeleted(Object source, SqlDataSourceStatusEventArgs e)
    {
        Label1.Text = e.AffectedRows + " row(s) were deleted";
    }
    protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
    {
        int x = 5;
    }
    protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
    {
        bool x = e.Cancel;
    }
    protected void GridView1_RowUpdated(object sender, GridViewUpdatedEventArgs e)
    {
        int x = e.AffectedRows;
    }
</script>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Domain Manager</title>
    <link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css' />
    <link href="~/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <asp:Label
        id="Label1"
        runat="server"
        forecolor="Red" />

    <h1>Godaddy</h1>
    <form id="form1" runat="server">

        <asp:SqlDataSource
            id="SqlDataSource1"
            runat="server"
            ConnectionString="<%$ ConnectionStrings:SQLconnect %>"
            SelectCommand="SELECT DomainName,InUse FROM DomainList"
            UpdateCommandType="Text"
            UpdateCommand="UPDATE DomainList SET InUse=@InUse WHERE (DomainName=@DomainName)"
            DeleteCommand="DELETE FROM DomainList WHERE DomainName=@DomainName"
            OnDeleted="OnDomainDeleted">
            <UpdateParameters>
                <asp:Parameter Name="DomainName" Type="String" />
                <asp:Parameter Name="InUse" Type="String" />
            </UpdateParameters>
        </asp:SqlDataSource>

        <asp:GridView
            id="GridView1"
            runat="server"
            AutoGenerateColumns="false"
            DataKeyNames="DomainName"
            AutoGenerateEditButton="true"
            AutoGenerateDeleteButton="true"
            EnableViewState="true"
            ViewStateMode="Enabled"
            DataSourceID="SqlDataSource1"
            AllowSorting="true"
            OnRowEditing="GridView1_RowEditing"
            OnRowUpdating="GridView1_RowUpdating"
            OnRowUpdated="GridView1_RowUpdated">
            <rowstyle backcolor="LightCyan"  
                   forecolor="Black" />
            <alternatingrowstyle backcolor="PaleTurquoise"  
                  forecolor="Black" />
            <columns>
                <asp:BoundField HeaderText="Domain Name" DataField="DomainName" ReadOnly="true" SortExpression="DomainName" />
                <asp:BoundField HeaderText="In Use" DataField="InUse" SortExpression="InUse" />
                <%--<asp:BoundField HeaderText="Domain Cost" DataField="DomainCost" />
                <asp:BoundField HeaderText="TLD" DataField="TLD" />
                <asp:BoundField HeaderText="Registrar" DataField="Registrar" />
                <asp:BoundField HeaderText="Expiration Date" DataField="ExpirationDate" />
                <asp:BoundField HeaderText="Status" DataField="Status" />
                <asp:BoundField HeaderText="Privacy" DataField="Privacy" />
                <asp:BoundField HeaderText="Forwarding URL" DataField="ForwardingURL" />
                <asp:BoundField HeaderText="Notes" DataField="Notes" />
                <asp:BoundField HeaderText="Department/Program" DataField="DepartmentProgram" />
                <asp:BoundField HeaderText="Program Contact" DataField="ProgramContact" />--%>
            </columns>
        </asp:GridView>

        <hr />

        <asp:SqlDataSource
            id="SqlDataSource2"
            runat="server"
            ConnectionString="<%$ ConnectionStrings:SQLconnect %>"
            SelectCommand="SELECT * FROM DomainList"
            InsertCommand="INSERT INTO DomainList (DomainName,InUse,DomainCost,TLD,Registrar,ExpirationDate,Status, 
                                    Privacy,ForwardingURL,Notes,DepartmentProgram,ProgramContact) VALUES (@DName,@IUse,@DCost,
                                    @TLD,@Registrar,@ExDate,@Status,@Privacy,@FURL,@Notes,@Dept,@PContact)" >
                <insertparameters>
                    <asp:FormParameter Name="DName" FormField="DomainNameBox" />
                    <asp:FormParameter Name="IUse" FormField="InUseBox" />
                    <asp:FormParameter Name="DCost" FormField="DomainCostBox" />
                    <asp:FormParameter Name="TLD" FormField="TLDBox" />
                    <asp:FormParameter Name="Registrar" FormField="RegistrarBox" />
                    <asp:FormParameter Name="ExDate" FormField="ExDateBox" />
                    <asp:FormParameter Name="Status" FormField="StatusBox" />
                    <asp:FormParameter Name="Privacy" FormField="PrivacyBox" />
                    <asp:FormParameter Name="FURL" FormField="FURLBox" />
                    <asp:FormParameter Name="Notes" FormField="NotesBox" />
                    <asp:FormParameter Name="Dept" FormField="DeptBox" />
                    <asp:FormParameter Name="PContact" FormField="PContactBox" />
                </insertparameters>
        </asp:SqlDataSource>

        <h1>Create New Godaddy Domain: </h1>

        <br />Domain Name: <asp:TextBox
            id="DomainNameBox"
            runat="server" />

        <asp:RequiredFieldValidator
            id="RequiredFieldValidator1"
            runat="server"
            ControlToValidate="DomainNameBox"
            Display="Static"
            ErrorMessage="You must enter a domain name" />

        <br />In Use? (yes/no): <asp:TextBox
            id="InUseBox"
            runat="server" />

        <br />Cost: <asp:TextBox
            id="DomainCostBox"
            runat="server" />

        <br />TLD: <asp:TextBox
            id="TLDBox"
            runat="server" />

        <br />Registrar: <asp:TextBox
            id="RegistrarBox"
            runat="server" />

        <br />Expiration Date: <asp:TextBox
            id="ExDateBox"
            runat="server" />

        <br />Status: <asp:TextBox
            id="StatusBox"
            runat="server" />

        <br />Privacy: <asp:TextBox
            id="PrivacyBox"
            runat="server" />

        <br />Forwarding URL: <asp:TextBox
            id="FURLBox"
            runat="server" />

        <br />Notes: <asp:TextBox
            id="NotesBox"
            runat="server" />

        <br />Department: <asp:TextBox
            id="DeptBox"
            runat="server" />

        <br />Program Contact: <asp:TextBox
            id="PContactBox"
            runat="server" />

        <br /><asp:Button
            id="Button1"
            runat="server"
            text="Create New Domain"
            onclick="InsertDomain" />

        <hr />

        <h1>Network Solutions</h1>

        <asp:GridView
            id="GridView2"
            runat="server"
            AutoGenerateColumns="false"
            AutoGenerateEditButton="true"
            DataKeyNames="DomainName"
            DataSourceID="SqlDataSource3">
            <rowstyle backcolor="LightCyan"  
                   forecolor="Black"
                   />
                <alternatingrowstyle backcolor="PaleTurquoise"  
                  forecolor="Black"
                  />
            <columns>
                <asp:BoundField HeaderText="Domain Name" DataField="DomainName" ReadOnly="true" />
                <asp:BoundField HeaderText="Account" DataField="AccountNo" />
                <asp:BoundField HeaderText="Points To" DataField="PointsTo" />
                <asp:BoundField HeaderText="Folder" DataField="Folder" />
                <asp:BoundField HeaderText="Auto Renew" DataField="AutoRenew" />
                <asp:BoundField HeaderText="Expiration Date" DataField="ExpirationDate" />
                <asp:BoundField HeaderText="WHOIS Admin" DataField="AdminContact" />
                <asp:BoundField HeaderText="WHOIS Tech" DataField="TechContact" />
                <asp:BoundField HeaderText="Account Holder" DataField="AccountHolder" />
                <asp:BoundField HeaderText="Private" DataField="Private" />
            </columns>
        </asp:GridView>

        <asp:SqlDataSource 
            id="SqlDataSource3"
            runat="server"
            DataSourceMode="DataReader"
            ConnectionString="<%$ ConnectionStrings:SQLconnect%>"
            SelectCommand="SELECT DomainName,AccountNo,PointsTo,Private,Folder,AutoRenew,ExpirationDate, 
                                AdminContact,TechContact,AccountHolder FROM NetworkSolutions"
            UpdateCommand="UPDATE NetworkSolutions SET AccountNo=@AccountNo,PointsTo=@PointsTo,Private=@Private,Folder=@Folder,AutoRenew=@AutoRenew,ExpirationDate=@ExpirationDate,
                            AdminContact=@AdminContact,TechContact=@TechContact,AccountHolder=@AccountHolder WHERE (DomainName=@DomainName)">
        </asp:SqlDataSource>

    </form>
</body>
</html>

解决方案:我有一个函数InsertDomain,它似乎正在捕获来自 GridViews 的更新。解决方案需要设置 ValidationGroup 以限制该验证影响整个页面。

【问题讨论】:

  • 如果您将以下内容添加到标记Direction="Input"中的更新参数中会怎样
  • 您能否发布表DomainList 的创建脚本?我很确定这与数据库中的数据类型有关。
  • 要获取这个脚本,可以到SQL Server Management Studio中的DomainList表,右击然后Script Table as>Create to
  • @MethodMan 没用。看起来Input 无论如何都是默认值。
  • 好的。伟大的。让我看看你的新脚本。

标签: c# asp.net sql-server gridview


【解决方案1】:

确保SqlDataSourceInUse参数的数据类型与数据库中同一列的数据类型匹配。

如果此列在 varchar 或 nvarchar 等数据库中为字符串类型,则您的更新将发生,因为您已在 SqlDataSource 中将数据类型指定为 string。否则会出问题。

在您发布完整页面代码后,我注意到验证器没有提到ValidationGroup,因此当文本框中没有条目时,gridview 中的Update 按钮不会回发。用以下代码替换验证器和按钮标记,然后它应该可以工作了。

      <asp:RequiredFieldValidator
            id="RequiredFieldValidator1"
            runat="server"
            ControlToValidate="DomainNameBox"
            Display="Static"
            ErrorMessage="You must enter a domain name"  ValidationGroup="Insert"  />
<asp:Button
            id="Button1"
            runat="server"
            text="Create New Domain"
            onclick="InsertDomain" ValidationGroup="Insert" />

此外,如果您看到“WebForms UnobtrusiveValidationMode 需要 ScriptResourceMapping..”的错误消息,请在 Web 配置文件中包含以下 appsetting。

<add key="ValidationSettings:UnobtrusiveValidationMode" value="None" />

【讨论】:

  • 在 SQL 中使用的是 nchar(3)。这应该适用于string 对吧?
  • 你能把它改成 varchar(3) 吗?另外,在此之前,您能否告诉我在网格视图中单击更新时是否看到任何错误?
  • 我把它改成了 varchar(3) 但还是不行。不,没有错误消息。
  • 然后发生了其他事情。我尝试了与您完全相同的场景,除了没有 SqlDataSource 的 OnDeleted 事件并且它运行良好。我猜你的代码隐藏中有一些东西正在取消网格的 UPDATE 命令。如果它不是太大,你可以发布你的代码隐藏吗?
  • 你能试试我刚才在回答中提到的吗?我很好奇您看到 e.Cancel 和 e.AffectedRows 的值是多少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多