我有一个RadGrid(Gridview),可以选择编辑和插入新项目。
在这两个选项中,我都有一个customvalidator来检查现有值,因此无法输入重复项。我坚持的是能够在文本框中使用findcontrol,只在编辑和插入过程中显示。
这适用于INSERT,因为我调用了GetInsertItem(),但是在编辑时抛出了一个错误,我坚持这个。我想在数据绑定和命令方法之外执行此操作。
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
TextBox txtAccountNumber = (TextBox)RadGrid1.MasterTableView.GetInsertItem().FindControl("txtAccountNumber");
List<GridDataItem> Items = (from item in RadGrid1.Items.Cast<GridDataItem>()
where item["AccountNumberView"].Text == txtAccountNumber.Text
select item).ToList();
args.IsValid = Items.Count() == 0;
}
这是编辑屏幕的图像。
ASPX:
Sort By Status: <asp:DropDownList ID="dd_Status" runat="server" Width="150px"
onselectedindexchanged="dd_Status_SelectedIndexChanged"
AutoPostBack="True">
<asp:ListItem Text="All" Value="0" Selected="True"></asp:ListItem>
<asp:ListItem Text="Active" Value="True"></asp:ListItem>
<asp:ListItem Text="Inactive" Value="False"></asp:ListItem>
</asp:DropDownList>
<br /><br />
<telerik:RadGrid ID="RadGrid1" runat="server" Skin="Vista" Width="500px"
GridLines="None" AllowFilteringByColumn="False" AllowSorting="True" OnExportCellFormatting="RadGrid1_ExportCellFormatting" DataSourceID="SqlDataSource1"
AllowAutomaticDeletes="true" AllowAutomaticUpdates="True" AutoGenerateEditColumn="True" AutoGenerateDeleteColumn="true" OnItemCommand="RadGrid1_ItemCommand" >
<MasterTableView AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDataSource1" ItemStyle-HorizontalAlign="Left" CommandItemDisplay="TopAndBottom">
<Columns>
<telerik:GridTemplateColumn HeaderText="ID" SortExpression="ID" UniqueName="ID" Visible="false" ReadOnly="true">
<ItemTemplate>
<asp:Label ID="lblIDView" runat="server" Text='<%# Bind("ID") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="ID" SortExpression="IDEdit" UniqueName="IDEdit" Visible="false">
<ItemTemplate />
<EditItemTemplate>
<asp:Label ID="lblID" runat="server" Text='<%# Bind("ID") %>'></asp:Label>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridBoundColumn DataField="AccountNumber" HeaderText="Sapphire Account Number"
SortExpression="AccountNumber" UniqueName="AccountNumberView" ReadOnly="true" ItemStyle-Width="400">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Sapphire Account Number" SortExpression="AccountNumber" UniqueName="AccountNumber" Visible="false">
<ItemTemplate />
<EditItemTemplate>
<asp:Textbox ID="txtAccountNumber" runat="server" Text='<%# Bind("AccountNumber") %>' />
<asp:RequiredFieldValidator ID="rfvAccountNumber" ControlToValidate="txtAccountNumber"
ErrorMessage="Sapphire Account Number is required" runat="server" ForeColor="Red"></asp:RequiredFieldValidator>
<asp:CustomValidator ID="cvAccountNumber" runat="server" ErrorMessage="Sapphire Account Number already exists"
ControlToValidate="txtAccountNumber" ForeColor="Red" OnServerValidate="cvAccountNumber_ServerValidate"></asp:CustomValidator>
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="Active" SortExpression="Active" UniqueName="Active" ItemStyle-Width="100" Visible="false">
<ItemTemplate />
<EditItemTemplate>
<asp:CheckBox ID="cbActive" runat="server" Checked='<%# GenerateBindString(Container.DataItem) %>' />
</EditItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderText="Status" SortExpression="Active" UniqueName="Active" ItemStyle-Width="100">
<ItemTemplate>
<asp:Label ID="lblActive" runat="server" Text='<%# Convert.ToBoolean(GenerateBindString(Container.DataItem)) == true ? "Active" : "Inactive" %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
<ValidationSettings CommandsToValidate="PerformInsert,Update" />
<ClientSettings>
<Selecting AllowRowSelect="True" />
</ClientSettings>
</telerik:RadGrid>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:LBCust %>"
SelectCommand="SELECT * FROM [LBX_Portal_AccountNumbers] WHERE ([Site] = @Site) AND (Active=@Active OR @Active = '0') ORDER BY AccountNumber"
DeleteCommand="DELETE FROM [LBX_Portal_AccountNumbers] WHERE [ID] = @ID"
InsertCommand="INSERT INTO [LBX_Portal_AccountNumbers] ([AccountNumber], [Site], [Active]) VALUES (@AccountNumber, @Site, @Active)"
UpdateCommand="UPDATE [LBX_Portal_AccountNumbers] SET [AccountNumber] = @AccountNumber, [Active] = @Active WHERE [ID] = @ID">
<SelectParameters>
<asp:ControlParameter ControlID="dd_Status" Name="Active"
PropertyName="SelectedValue" Type="String" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="ID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="AccountNumber" Type="String" />
<asp:Parameter Name="Site" Type="String" />
<asp:Parameter Name="Active" Type="Boolean" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="AccountNumber" Type="String" />
<asp:Parameter Name="Active" Type="Boolean" />
</UpdateParameters>
</asp:SqlDataSource>
CS:
public partial class Admin_CustomerAccountManager : System.Web.UI.Page
{
public string SiteName = WebConfigurationManager.AppSettings["Site"].ToString();
protected void Page_Load(object sender, EventArgs e)
{
Label LBXTitle = (Label)Master.FindControl("lbxTitle");
LBXTitle.Text = "Customer Sapphire Account Number Manager";
if (!this.IsPostBack)
{
SqlDataSource1.SelectParameters.Add("Site", DbType.String, SiteName);
}
}
protected void dd_Status_SelectedIndexChanged(object sender, EventArgs e)
{
RadGrid1.DataBind();
}
protected bool GenerateBindString(object dataItem)
{
bool ret = false;
// if column is null set checkbox.checked = false
if ((DataBinder.Eval(dataItem, "Active")).ToString() == "")
ret = false;
else // set checkbox.checked to boolean value in Status column
ret = (bool)DataBinder.Eval(dataItem, "Active");
return ret;
}
protected void RadGrid1_ItemCommand(object source, Telerik.Web.UI.GridCommandEventArgs e)
{
Page.Validate();
if (Page.IsValid)
{
if (e.CommandName == "PerformInsert")
{
GridEditFormItem gridEditFormItem = (GridEditFormItem)e.Item;
Label lblID = (Label)gridEditFormItem.FindControl("lblID");
TextBox txtAccountNumber = (TextBox)gridEditFormItem.FindControl("txtAccountNumber");
CheckBox cbActive = (CheckBox)gridEditFormItem.FindControl("cbActive");
bool isActive = true;
string SqlStr = "INSERT INTO [LBX_Portal_AccountNumbers] ([AccountNumber], [Site], [Active])";
SqlStr += " VALUES ('" + txtAccountNumber.Text + "'" + ", '" + SiteName + "'" + ", '" + isActive + "')";
SqlDataSource1.InsertCommand = SqlStr;
SqlDataSource1.Insert();
}
if (e.CommandName == "Update")
{
GridEditFormItem gridEditFormItem = (GridEditFormItem)e.Item;
Label lblID = (Label)gridEditFormItem.FindControl("lblID");
TextBox txtAccountNumber = (TextBox)gridEditFormItem.FindControl("txtAccountNumber");
CheckBox cbActive = (CheckBox)gridEditFormItem.FindControl("cbActive");
bool isActive = false;
if (cbActive.Checked)
isActive = true;
else
isActive = false;
string SqlStr = "UPDATE [LBX_Portal_AccountNumbers] SET [AccountNumber] = '" + txtAccountNumber.Text;
SqlStr += "', [Active] = '" + isActive + "' WHERE [ID] = " + lblID.Text;
SqlDataSource1.UpdateCommand = SqlStr;
SqlDataSource1.Update();
}
}
}
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
TextBox txtAccountNumber = RadGrid1.FindControl("txtAccountNumber") as TextBox;
List<GridDataItem> Items = (from item in RadGrid1.Items.Cast<GridDataItem>()
where item["AccountNumberView"].Text == txtAccountNumber.Text
select item).ToList();
args.IsValid = Items.Count() == 0;
}
}
答案 0 :(得分:2)
看起来验证事件中的GridView.FindControl永远不会工作,你怎么能访问需要像这样验证的字符串:
这是验证目标控制值的方法:
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
string textToBeValidated = args.Value;
}
以下是您可以访问实际控件的方法。在使用ServerValidate上下文时,GridView.FindControl将不会产生任何结果,因此您必须查看已编辑/插入的行。
protected void cvAccountNumber_ServerValidate(object source, ServerValidateEventArgs args)
{
//find your editing row...
GridViewRow editedRow = RadGrid1.Rows[RadGrid1.EditIndex];
//now serch row for your control...
TextBox txtAccountNumber = (TextBox)editedRow.FindControl("txtAccountNumber");
TextBox txtId = (TextBox)editedRow.FindControl("txtId");
}
答案 1 :(得分:2)
首先,您的代码很容易进行SQL注入,但这不是您最初的问题。
您无法遍历GridDataItems以查找重复项。如果您稍后对网格进行分页,则无法找到它。
首先,您可以使用RadGrid的InsertCommand和UpdateCommand事件来简化。然后使用ADO.Net或您喜欢的任何方法检查副本。
protected void RadGrid1_InsertCommand(object source, GridCommandEventArgs e)
{
try
{
var gridEditFormItem = (GridEditFormItem) e.Item;
var txtAccountNumber = (TextBox)gridEditFormItem.FindControl("txtAccountNumber");
var cbActive = (CheckBox)gridEditFormItem.FindControl("cbActive");
// TODO: Check duplicate against database
string SqlStr = "INSERT INTO [LBX_Portal_AccountNumbers] ([AccountNumber], [Site], [Active])" +
" VALUES ('" + txtAccountNumber.Text + "'" + ", '" + SiteName + "'" + ", '" + isActive + "')";
SqlDataSource1.InsertCommand = SqlStr;
SqlDataSource1.Insert();
}
catch (Exception ex)
{
// Log Error
}
}
protected void RadGrid1_UpdateCommand(object source, GridCommandEventArgs e)
{
try
{
var gridEditFormItem = (GridEditFormItem) e.Item;
int id = Convert.ToInt32(e.Item.OwnerTableView.DataKeyValues[e.Item.ItemIndex]["ID"]);
var txtAccountNumber = (TextBox)gridEditFormItem.FindControl("txtAccountNumber");
var cbActive = (CheckBox)gridEditFormItem.FindControl("cbActive");
// TODO: Check duplicate against database
string SqlStr = "UPDATE [LBX_Portal_AccountNumbers] SET [AccountNumber] = '" + txtAccountNumber.Text +
"', [Active] = '" + isActive + "' WHERE [ID] = " + lblID.Text;
SqlDataSource1.UpdateCommand = SqlStr;
SqlDataSource1.Update();
}
catch (Exception ex)
{
// Log Error
}
}
答案 2 :(得分:0)
这就是我的建议以及如何解决这个问题。
在您遇到错误的代码中加上一个断点。
运行Debug程序。该程序将在断点处停止。
在Watch Windows中添加您的对象并查看它包含的值。不要害怕。 Watch Window非常强大。您可以添加对象或其任何属性以查看它包含的值。你特别想关注空值。
一旦识别出来自它的null异常,请在Watch窗口中修复该语法并再次运行该程序。