I have a page that contains a data repeater which in turn contains a button that is meant to delete a delete a record from an SQL database. When this button is clicked I receive the following error: Procedure or function 'usp_setKS3_DeleteAssessment' expects parameter '#intAssessmentId', which was not supplied.
If I comment out the KS3_DataSource_Assessment.Delete(); line in the code behind the page loads without error and displays the message, but does not delete the record (which I expect as the line was commented out). I have no idea what to do to make this work... any ideas?
ASP.net
<asp:SqlDataSource ID="KS3_DataSource_Assessment" runat="server" ConnectionString="<%$ ConnectionStrings:sqlWriter %>" ProviderName="System.Data.SqlClient" SelectCommandType="StoredProcedure" SelectCommand="usp_getKS3_ManageAssessments" OnSelected="KS3_DataSource_Assessment_Selected" DeleteCommand="usp_setKS3_DeleteAssessment">
<SelectParameters>
<asp:ControlParameter ControlID="KS3_DropDown_ACYear" PropertyName="SelectedValue" Name="intACYearId" Type="Int32" />
<asp:ControlParameter ControlID="KS3_DropDown_Subject" PropertyName="SelectedValue" Name="intSubjectId" Type="Int32" />
<asp:ControlParameter ControlID="KS3_DropDown_Year" PropertyName="SelectedValue" Name="intYearGroup" Type="Int32" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="intAssessmentId" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
<asp:Repeater runat="server" ID="KS3_Repeater_Assessments" EnableViewState="true" DataSourceID="KS3_DataSource_Assessment" OnItemDataBound="KS3_Repeater_Assessments_ItemDataBound">
<ItemTemplate>
<!-- Assessments -->
<asp:Table runat="server" ID="KS3_Table_Assessments" CssClass="width100pc">
<asp:TableRow CssClass="SectionSubHeader">
<asp:TableCell><%# Eval("txtAssessmentTitle").ToString() %></asp:TableCell>
<asp:TableCell CssClass="width25px alignCenter alignVerticalMiddle" RowSpan="2"><asp:ImageButton SkinID="imgButtonDelete" runat="server" ID="KS3_Button_DeleteAssessment" OnCommand="KS3_Button_DeleteAssessment_Command" CommandArgument='<%# Eval("intAssessmentID").ToString() %>' OnClientClick="return confirm('Are you sure you want to delete this assessment?\n\nOnce deleted all data is lost.');" /></asp:TableCell>
<asp:TableCell CssClass="width25px alignCenter alignVerticalMiddle" RowSpan="2">Up</asp:TableCell>
<asp:TableCell CssClass="width25px alignCenter alignVerticalMiddle" RowSpan="2">Down</asp:TableCell>
</asp:TableRow>
<asp:TableRow CssClass="BackgroundBlack fontStyleItalic">
<asp:TableCell><%# Eval("txtAssessmentDescription").ToString() %></asp:TableCell>
</asp:TableRow>
</asp:Table>
<!-- Columns -->
<asp:SqlDataSource ID="KS3_DataSource_Columns" runat="server" ConnectionString="<%$ ConnectionStrings:sqlWriter %>" ProviderName="System.Data.SqlClient" SelectCommandType="StoredProcedure" SelectCommand="usp_getKS3_ManageAssessments">
<SelectParameters>
<asp:Parameter Name="intACYearId" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:Repeater>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
}
protected void KS3_Button_SelectSubject_Click(object sender, EventArgs e)
{
if (KS3_DropDown_Subject.SelectedIndex == 0) { DisplayMessage("Validation Error", "Please select a subject from the list below.", "error"); KS3_Panel_DataToManage.Visible = false; }
else if (KS3_DropDown_Year.SelectedIndex == 0) { DisplayMessage("Validation Error", "Please select a year group from the list below.", "error"); KS3_Panel_DataToManage.Visible = false; }
else
{
//No errors detected, start data display
Master.systemMessageHide();
KS3_Panel_DataToManage.Visible = true;
//Update display
KS3_Label_Title.Text = KS3_DropDown_Subject.SelectedItem.Text.Trim() + " - " + KS3_DropDown_Year.SelectedItem.Text.Trim();
//Bind the new data to the repeater
KS3_Repeater_Assessments.DataBind();
}
}
public void DisplayMessage(string title, string message, string type)
{
Master.systemMessageShow(title, message, type);
}
protected void KS3_DataSource_Assessment_Selected(object sender, SqlDataSourceStatusEventArgs e)
{
if (e.AffectedRows < 1) { KS3_Panel_NoAssessments.Visible = true; }
else { KS3_Panel_NoAssessments.Visible = false; }
}
protected void KS3_Button_DeleteAssessment_Command(object sender, CommandEventArgs e)
{
KS3_Label_Title.Text = "DataSubmitted";
KS3_DataSource_Assessment.DeleteParameters["intAssessmentId"].DefaultValue = e.CommandArgument.ToString();
Trace.Write("Item Value: " + e.CommandArgument.ToString());
KS3_DataSource_Assessment.Delete();
KS3_Repeater_Assessments.DataBind();
DisplayMessage("Assessment Delete", "The selected assessment has been deleted and all associated data has been removed.", "success");
}
It looks that you are missing this attribute of the data source control:
DeleteCommandType="StoredProcedure"
Default value is Text, which makes control think that the command provided is an SQL statement. Since you are using stored procedure, this is not the behavior you want.
I have 20 textboxes and a dropdownlist on my form.
I am using EditItemTemplate and a SqlDataSource for editing and inserting data.
I replaced a dropdownlist with a textbox and things didn't work. With the textbox, the form was working fine.
Initially, I had:
<asp:TextBox ID="IDTextBox" runat="server" Text='<%# Bind("EPMProjectUID") %>'/>
<asp:SqlDataSource ID="dsManageProject" runat="server"
SelectCommand="SELECT [EPMProjectUID] from Table"
UpdateCommand="UPDATE [Table] SET [EPMProjectUID] = #EPMProjectUID "
InsertCommand="Insert into [Table] values(EPMProjectUID)"
<SelectParameters>
<asp:Parameter Name="EPMScheduleUID" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="EPMScheduleUID" />
</UpdateParameters>
<InsertParameters>
<asp:Parameter Name="EPMScheduleUID" />
<InsertParameters>
</asp:SqlDataSource>
And the things were working,I use to get the data and update it and even store it.
But now, I want a dropdownlist here, so I added
<asp:DropDownList ID="UIDDropDownList" runat="server"></asp:DropDownList>
In the cs file, I wrote
DB db1 = new DB(Global.ConnStringName);
db1.QueryText = #"SELECT UID, ProjectName FROM Table ";
DataTable dt = db1.GetDataTable();
DropDownList ddlUID = (DropDownList)FormView1.FindControl("UIDDropDownList");
if (ddlUID != null)
{
ddlUID.DataSource = dt;
ddlUID.DataTextField = "ProjectName";
ddlUID.DataValueField = "UID";
ddlUID.DataBind();
}
And this helps me to load the data, but if I try to insert/update anything, it stores as null.
I wanted to insert a variable into a table in db using the SqlDataSource. Below is my code in aspx:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ACM_DBConnectionString %>"
DeleteCommand="DELETE FROM [ContestRelation] WHERE [relationid] = #relationid"
InsertCommand="INSERT INTO [ContestRelation] ([contestid]) VALUES (#contestid)"
SelectCommand="SELECT [relationid], [contestid] FROM [ContestRelation]"
UpdateCommand="UPDATE [ContestRelation] SET [contestid] = #contestid WHERE [relationid] = #relationid">
<DeleteParameters>
<asp:Parameter Name="relationid" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="contestid" Type="Int32" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="contestid" Type="Int32" />
<asp:Parameter Name="relationid" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
and the code behind:
protected void ConfirmContest_Click(object sender, EventArgs e)
{
try
{
foreach (GridItem item in RadGrid1.MasterTableView.Items)
{
GridDataItem dataitem = (GridDataItem)item;
TableCell cell = dataitem["selectContest"];
CheckBox checkBox = (CheckBox)cell.Controls[0];
if (checkBox.Checked)
{
string value = dataitem.GetDataKeyValue("contestid").ToString();
SqlDataSource1.InsertParameters.Add("contestid", value);
SqlDataSource1.Insert();
}
}
}
catch (Exception ex)
{
Response.Write("<script language='javascript'>alert('No data selected .');</script>");
}
}
The "value" variable is not inserted into the database table. Can anyone point me my mistakes? Thanks in advance.
Problem Solved!
I actually cannot add an existing insert parameter, instead, I change to following code
string value = dataitem.GetDataKeyValue("contestid").ToString();
SqlDataSource1.InsertParameters.Add("contestid", value);
SqlDataSource1.Insert();
to following code. And the problem is solved.
string value = dataitem.GetDataKeyValue("contestid").ToString();
SqlDataSource1.InsertParameters["contestid"].DefaultValue = value;
SqlDataSource1.Insert();
I have created a bulk editable gridview web user control (BulkEditGridView.ascx) from the below link by just copy pasting, I did not include any external code:
http://blogs.msdn.com/b/mattdotson/archive/2005/11/09/real-world-gridview-bulk-editing.aspx
I added BulkEditGridView control into another web user control OrderDetailGridView.ascx and add datasource to BulkEditGridView
What I am tring to do is to have an interdependent dropdownlist and 2 textboxes inside my BulkEditGridView. (see OrderDetailGridView.ascx source code) At the moment when dropdownlist changes, textboxes remains unchanged, after save button is clicked, the corresponding values are updated and visible in textboxes.
However what I want to do is when dropdownlist changes, before clicking save button, I want to see corresponding values inside the textboxes, and then be able to save with save button.
I tried to set autpostback=true and ddl_MaterialCode_SelectedIndexChanged event to change the textboxes, but then save button does not work,
I tried to put an updatepanel, again the same, save button did not work.
Below are the source codes of my code in which save button works where textboxes updated after save is clicked.
BulkEditGridView.ascx source code (I did not add anything myself, just copy paste):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Exportal.Controls
{
public partial class BulkEditGridView : System.Web.UI.WebControls.GridView
{
private List<int> dirtyRows = new List<int>();
[IDReferenceProperty(typeof(Control))]
public string SaveButtonID
{
get
{
string val = (string)this.ViewState["SaveButtonID"];
if (val == null)
{
return string.Empty;
}
return val;
}
set
{
this.ViewState["SaveButtonID"] = value;
}
}
protected override GridViewRow CreateRow(int rowIndex, int dataSourceIndex, DataControlRowType rowType, DataControlRowState rowState)
{
return base.CreateRow(rowIndex, dataSourceIndex, rowType, rowState | DataControlRowState.Edit);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
//Attach an event handler to the save button.
if (false == string.IsNullOrEmpty(this.SaveButtonID))
{
Control btn = RecursiveFindControl(this.NamingContainer, this.SaveButtonID);
if (null != btn)
{
if (btn is Button)
{
((Button)btn).Click += new EventHandler(SaveClicked);
}
}
}
}
private void SaveClicked(object sender, EventArgs e)
{
this.Save();
this.DataBind();
}
protected override void InitializeRow(GridViewRow row, DataControlField[] fields)
{
base.InitializeRow(row, fields);
foreach (DataControlFieldCell cell in row.Cells)
{
if (cell.Controls.Count > 0)
{
AddChangedHandlers(cell.Controls);
}
}
}
private void AddChangedHandlers(ControlCollection controls)
{
foreach (Control ctrl in controls)
{
if (ctrl is TextBox)
{
((TextBox)ctrl).TextChanged += new EventHandler(this.HandleRowChanged);
}
else if (ctrl is CheckBox)
{
((CheckBox)ctrl).CheckedChanged += new EventHandler(this.HandleRowChanged);
}
else if (ctrl is DropDownList)
{
((DropDownList)ctrl).SelectedIndexChanged += new EventHandler(this.HandleRowChanged);
}
}
}
void HandleRowChanged(object sender, EventArgs args)
{
GridViewRow row = ((Control)sender).NamingContainer as GridViewRow;
if (null != row && !dirtyRows.Contains(row.RowIndex))
{
dirtyRows.Add(row.RowIndex);
}
}
public void Save()
{
foreach (int row in dirtyRows)
{
this.UpdateRow(row, false);
}
dirtyRows.Clear();
}
private Control RecursiveFindControl(Control namingcontainer, string controlName)
{
Control c = namingcontainer.FindControl(controlName);
if (c != null)
return c;
if (namingcontainer.NamingContainer != null)
return RecursiveFindControl(namingcontainer.NamingContainer, controlName);
return null;
}
}
}
OrderDetailGridView.ascx source code:
<cc1:BulkEditGridView ID="BulkEditGridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="RowNo" DataSourceID="SqlDataSource1" SaveButtonID="btn_Kaydet">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="PONumber" HeaderText="PONumber" SortExpression="PONumber" />
<asp:TemplateField HeaderText="MaterialCode" SortExpression="MaterialCode">
<EditItemTemplate>
<asp:DropDownList ID="ddl_MaterialCode" runat="server" DataSourceID="SqlDataSource2"
DataTextField="MaterialCode" DataValueField="MaterialCode" SelectedValue='<%# Bind("MaterialCode") %>'
OnSelectedIndexChanged="ddl_MaterialCode_SelectedIndexChanged" >
</asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="MaterialDescription" SortExpression="MaterialDescription">
<EditItemTemplate>
<asp:TextBox ID="txt_MaterialDescription" runat="server" Text='<%# Bind("MaterialDescription") %>'
Enabled="false"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="MaterialCategory" SortExpression="MaterialCategory">
<EditItemTemplate>
<asp:TextBox ID="txt_MaterialCategory" runat="server" Text='<%# Bind("MaterialCategory") %>'
Enabled="false"></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="UnitOfMeasure" HeaderText="UnitOfMeasure" SortExpression="UnitOfMeasure" />
<asp:BoundField DataField="Quantity" HeaderText="Quantity" SortExpression="Quantity" />
<asp:BoundField DataField="ContainerType" HeaderText="ContainerType" SortExpression="ContainerType" />
<asp:BoundField DataField="LoadingDate" HeaderText="LoadingDate" SortExpression="LoadingDate" />
</Columns>
</cc1:BulkEditGridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:MyDbConn %>"
DeleteCommand="DELETE FROM [OrderDetail] WHERE [RowNo] = #RowNo" InsertCommand="INSERT INTO [OrderDetail] ([FileNo], [PONumber], [MaterialCode], [MaterialDescription], [MaterialCategory], [UnitOfMeasure], [Quantity], [ContainerType], [LoadingDate]) VALUES (#FileNo, #PONumber, #MaterialCode, #MaterialDescription, #MaterialCategory, #UnitOfMeasure, #Quantity, #ContainerType, #LoadingDate)"
SelectCommand="SELECT * FROM [OrderDetail]" UpdateCommand="UPDATE [OrderDetail] SET [FileNo] = #FileNo, [PONumber] = #PONumber, [MaterialCode] = #MaterialCode, [MaterialDescription] = #MaterialDescription, [MaterialCategory] = #MaterialCategory, [UnitOfMeasure] = #UnitOfMeasure, [Quantity] = #Quantity, [ContainerType] = #ContainerType, [LoadingDate] = #LoadingDate WHERE [RowNo] = #RowNo">
<DeleteParameters>
<asp:Parameter Name="RowNo" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="FileNo" Type="Int32" />
<asp:Parameter Name="PONumber" Type="String" />
<asp:Parameter Name="MaterialCode" Type="String" />
<asp:Parameter Name="MaterialDescription" Type="String" />
<asp:Parameter Name="MaterialCategory" Type="String" />
<asp:Parameter Name="UnitOfMeasure" Type="String" />
<asp:Parameter Name="Quantity" Type="Int32" />
<asp:Parameter Name="ContainerType" Type="String" />
<asp:Parameter Name="LoadingDate" Type="String" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="FileNo" Type="Int32" />
<asp:Parameter Name="PONumber" Type="String" />
<asp:Parameter Name="MaterialCode" Type="String" />
<asp:Parameter Name="MaterialDescription" Type="String" />
<asp:Parameter Name="MaterialCategory" Type="String" />
<asp:Parameter Name="UnitOfMeasure" Type="String" />
<asp:Parameter Name="Quantity" Type="Int32" />
<asp:Parameter Name="ContainerType" Type="String" />
<asp:Parameter Name="LoadingDate" Type="String" />
<asp:Parameter Name="RowNo" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:MyDbConn %>"
SelectCommand="SELECT [MaterialCode] FROM [Materials]"></asp:SqlDataSource>
<asp:Button ID="btn_Kaydet" runat="server" Text="Save" />
OrderDetailGridView.ascx.cs source code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using SOrderDetailData;
using System.Data;
namespace Exportal.Controls
{
public partial class OrderDetailGridView : System.Web.UI.UserControl
{
protected void ddl_MaterialCode_SelectedIndexChanged(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt = OrderDetailData.GetMaterials();
DropDownList ddl_MaterialCode = (DropDownList)sender;
GridViewRow r = (GridViewRow)ddl_MaterialCode.Parent.Parent;
TextBox txt_MaterialDescription = (TextBox)r.FindControl("txt_MaterialDescription");
TextBox txt_MaterialCategory = (TextBox)r.FindControl("txt_MaterialCategory");
txt_MaterialDescription.Text = dt.Rows[ddl_MaterialCode.SelectedIndex]["MaterialDescription"].ToString();
txt_MaterialCategory.Text = dt.Rows[ddl_MaterialCode.SelectedIndex]["MaterialCategory"].ToString();
}
}
}
You will probably need to persist List<int> dirtyRows so that it can survive the post back. I would recommend either the Cache or Session, however check out this MSDN article Nine Options for Managing Persistent User State in Your ASP.NET Application for all of the options available.
Two things you should try:
Put a break-point on the code below and debug. Check that the app is reaching this btn...
if (null != btn) {
if (btn is Button) {
((Button)btn).Click += new EventHandler(SaveClicked);
}
}
After verifying that, you should add this button to the script manager
if (null != btn) {
if (btn is Button) {
((Button)btn).Click += new EventHandler(SaveClicked);
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(btn);
}
}
Does this control is inside an updatepanel somehow (maybe your mastepage has an updatepanel for all the content)?
If all you want to do is populate the textboxes with the selected values from the dropdowns, I would suggest jquery...
$('.dropdownclass').change(function() {
$(this).closest('tr').find('.textboxclass').val($(this).val());
});
Then you don't have to do additonal postbacks and hopefully your button click will work.
If all you want to do is populate the textboxes with the selected values from the dropdowns, I would also suggest jquery like someone wrote before...
But if you need to do something more when the dropdown changes... You need to use the RowCommand event of your grid.
This might help RowCommand
Short story:
add OnRowCommand="myGrid_RowCommand" to the properties of the grid
add CommandName="ddlChanged" to the properties of the dropdown in the grid
if you have more than 1 command in every row of the grid the myGrid_RowCommand function should look like this
void myGrid_RowCommand(Object sender, GridViewCommandEventArgs e) {
if(e.CommandName=="ddlChanged")
{// Do something
}
if(e.CommandName == "ddl2Changed")
{// Do something else
}
...
}
I am making a WebForm in asp.net and I want to display gridview with data from asp:SqlDataSource
My problem becomes when I try to skip (pass null) values for some of the Parameters.
Here is some snippets of my code
In aspx file sqldatasource looks like
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ApplicationServices %>"
SelectCommand="art_bat_art" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="art_naz" DefaultValue="HLA" ConvertEmptyStringToNull="true" Type="String" />
<asp:Parameter Name="art_sifra" DbType="String" Direction="Input"/>
<asp:Parameter Name="vrsta_id" DefaultValue="3" ConvertEmptyStringToNull="true" Type="Int32" />
<asp:Parameter Name="podvrsta_id" DefaultValue="13" ConvertEmptyStringToNull="true"
Type="Int32" />
<asp:Parameter Name="podgrupa2" DefaultValue="1365" ConvertEmptyStringToNull="true" Type="Int32" />
<asp:Parameter Name="podosobine" DefaultValue="1:9241" ConvertEmptyStringToNull="true"
Type="String" />
<asp:Parameter Name="podosobineOR" DefaultValue="true" ConvertEmptyStringToNull="true"
Type="Boolean" />
</SelectParameters>
My grid looks like this:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="id" DataSourceID="SqlDataSource1">
And troubles comes in code behind
One of parameters for my stored procedure is optional, If i pass it as null in SQL the stored procedure is
going to execute anyway.
I am trying to skip and pass that parameter as follows
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click1(object sender, EventArgs e)
{
SqlDataSource1.SelectParameters["art_sifra"].DefaultValue = DBNull.Value; //Cannot implicitly convert type
SqlDataSource1.SelectParameters["art_sifra"].DefaultValue = System.Data.SqlTypes.SqlString.Null; //Cannot implicitly convert type
SqlDataSource1.SelectParameters["art_sifra"].DefaultValue = System.Data.SqlTypes.SqlString.Null.ToString(); //IT compiles but i get NULL as text in SQL
//IF I Just skip seting of this parametar, My SqlDataSource won't call stored proce
SqlDataSource1.SelectParameters["art_sifra"].DefaultValue = string.Empty; //Again no execution of stored proce
//Even if I call SqlDataSource1.DataBind(); //nothing cames to sql
GridView1.DataBind();
}
}
You'll have to edit your SQL (or stored proc) to be able to handle an optional parameter.
ie: if you have:
SELECT blah FROM yourTable WHERE art_sifra = #art_sifra
change it to:
SELECT blah FROM yourTable WHERE (art_sifra = #art_sifra OR #art_sifra = '')
and then just change ConvertEmptyStringToNull="false" and set your select parameter to "":
SqlDataSource1.SelectParameters["art_sifra"].DefaultValue = "";
Also need to set CancelSelectOnNullParameter="false" on your datasource.
DBNull.Value; //Cannot implicitly convert type
Have you tried casting it? E.g.
DBNull.Value.Tostring()