I have one stored procedure called VideoGalleryDelete . I am using FormView and Gridview to insert, update, show and delete data. VideoGallery is my primary table with PK VideoId and it has a foreign key as CategoryId .
When i click Delete linkButton, its says Procedure or function has too many arguments specified
This is my SP :
ALTER PROCEDURE [dbo].[VideoGalleryDelete]
#VideoId int
AS
BEGIN
DELETE FROM [dbo].[VideoGallery]
WHERE VideoId = #VideoId
END
GridView and its assigned SqlDataSource :
<asp:GridView ID="gvVideo" CssClass="table" runat="server" OnSelectedIndexChanged="gvVideo_SelectedIndexChanged" AutoGenerateColumns="False" DataKeyNames="VideoId,CategoryId" DataSourceID="sdVideoList">
<Columns>
<asp:BoundField DataField="VideoId" Visible="false" HeaderText="VideoId" InsertVisible="False" ReadOnly="True" SortExpression="VideoId" />
<asp:BoundField DataField="VideoLink" HeaderText="Video Link" SortExpression="VideoLink" />
<asp:BoundField DataField="CategoryId" HeaderText="Category Id" SortExpression="CategoryId" />
<asp:TemplateField ItemStyle-CssClass="Center" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:ImageButton ImageUrl="~/images/edit.png" ID="lnkedit" Style="margin-left: 15px" CommandName="Select" runat="server" Width="20px"></asp:ImageButton>
<asp:ImageButton ImageUrl="~/images/delete.png" ID="lnkDelete" CommandName="Delete" Style="margin-left: 15px" runat="server" Width="20px" OnClientClick="return ConfirmDelete();"></asp:ImageButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="sdVideoList" runat="server" ConnectionString="<%$ ConnectionStrings:WebAAERT_DBConnectionString %>" DeleteCommand="VideoGalleryDelete" DeleteCommandType="StoredProcedure" SelectCommand="VideoGallerySelect" SelectCommandType="StoredProcedure">
<DeleteParameters>
<asp:Parameter Name="VideoId" Type="Int32" />
</DeleteParameters>
<SelectParameters>
<asp:Parameter DefaultValue="0" Name="CategoryId" Type="Int32" />
</SelectParameters>
I think you're misusing the DataKeyNames property of the grid view control.This property should ideally contain only the primary key field(s) to identify the current row.Also every single value set on this property will be passed through to the Delete command.
Your delete stored proc takes one parameter but two values are being passed through beacuase of DataKeyNames="VideoId,CategoryId".So you can do what #Chris Flynn suggested or change your grid view to DataKeyNames="VideoId"
I have this code that present a gridview that retrieved the data from 2 datasources.
each line present an order details and the last column present the order status.
the order status should be updateable in a dropdownlist .
<asp:GridView runat="server" AutoGenerateColumns="False" DataSourceID="OrderDataSource"
CssClass="DataTables">
<Columns>
<asp:CommandField ShowEditButton="true" />
<asp:BoundField DataField="oID" HeaderText="oId" SortExpression="oId" ReadOnly="true" />
<asp:BoundField DataField="DateOpened" HeaderText="DateOpened" SortExpression="DateOpened"
ReadOnly="true" />
<asp:BoundField DataField="rName" HeaderText="rName" SortExpression="rName" ReadOnly="true" />
<asp:BoundField DataField="DateOfArrival" HeaderText="DateOfArrival" SortExpression="DateOfArrival"
ReadOnly="true" />
<asp:BoundField DataField="Quantity" HeaderText="Quantity" SortExpression="Quantity"
ReadOnly="true" />
<asp:BoundField DataField="sName" HeaderText="sName" SortExpression="sName" ReadOnly="true" />
<asp:TemplateField HeaderText="osName" SortExpression="osName">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="StatusDataSource"
DataTextField="osName" DataValueField="osID" SelectedValue='<%# Bind("osName") %>'>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("osName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="OrderDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:igroup9_prodConnectionString %>"
SelectCommand="spGetOrdersListForProject" SelectCommandType="StoredProcedure"
UpdateCommand="Update[Orders] set [osID] =#osID where [oID]=#oID">
<SelectParameters>
<asp:ControlParameter ControlID="ProjectIDHolder" DefaultValue="" Name="ProjectID"
PropertyName="Value" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="osID" Type="Int32" />
<asp:Parameter Name="oID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="StatusDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:igroup9_prodConnectionString %>"
SelectCommand="spGetOrderStatus" SelectCommandType="StoredProcedure"></asp:SqlDataSource>
The problem is that when i'm trying to edit a column in the gridview i get this error: (after i click the edit button)
Server Error in '/Maestro' Application.
'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
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.
Exception Details: System.ArgumentOutOfRangeException: 'DropDownList1' has a SelectedValue which is invalid because it does not exist in the list of items.
Parameter name: value
Error seems clear to me. The values in the DropDownList don't contain the value that you're trying to set as the selected value. This is probably because the values are from the osID column and the selected value is from the osName column. Whatever the selected value ends up being, it should come from the data source which means you should probably use the same column (or a foreign key relationship).
You should probably change it to...
SelectedValue='<%# Bind("osID") %>'
and make sure that spGetOrdersListForProject returns the osID.
I set up an Sqldatasource and a Gridview:
<asp:SqlDataSource ID="DetailsSQLDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:aspnet-WebApplication6-20131007103938ConnectionString1 %>"
SelectCommand="SELECT [ProjectID], [ProjectName], [CreatorID], [Deadline] FROM [tProject] WHERE 1=1"
>
<SelectParameters>
<asp:Parameter Type="String" Name="ProjectID"></asp:Parameter>
</SelectParameters>
</asp:SqlDataSource>
<asp:GridView ID="GridView1" runat="server" DataSourceID="DetailsSQLDataSource" AutoGenerateColumns="False" DataKeyNames="ProjectID" OnRowUpdated="GridView1_RowUpdated" OnRowUpdating="GridView1_RowUpdating">
<Columns>
<asp:BoundField DataField="ProjectID" HeaderText="ProjectID" ReadOnly="True" SortExpression="ProjectID"></asp:BoundField>
<asp:BoundField DataField="ProjectName" HeaderText="ProjectName" SortExpression="ProjectName"></asp:BoundField>
<asp:BoundField DataField="CreatorID" HeaderText="CreatorID" SortExpression="CreatorID"></asp:BoundField>
<asp:BoundField DataField="Deadline" HeaderText="Deadline" SortExpression="Deadline"></asp:BoundField>
</Columns>
</asp:GridView>
I have tested the selectcommand, and it returns a table with 4 rows. Yet there is no data to show in the gridview. The codebehind is almost empty and surely doesn't affect these controls. Can it be something with the connection? How can I test that?
Call .DataBind() to actually force the data to be bound to the grid, like this:
GridView1.DataBind();
I'm trying to allow for editing of the items in a GridView (the DataSource is a database connection). Every example I find has complicated examples implemented within. I'd like to know what the simplest change(s) I need to do are in order to allow for editing of items in the GridView.
In other words, how can I modify the following to allow for editing?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSourceWS">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="id" HeaderText="id" InsertVisible="False" ReadOnly="True" SortExpression="id" />
<asp:BoundField DataField="NAME" HeaderText="NAME" SortExpression="NAME" />
<asp:BoundField DataField="ACCESS_TO" HeaderText="ACCESS_TO" SortExpression="ACCESS_TO" />
</Columns>
</asp:GridView>
Obviously I'd need to add code as well, but I'm just not sure how to start with this.
EDIT: I thought I'd specified, but I didn't - it's an SQLDataSource.
There are several thing you need to do to enable editing
Assuming that your data source is an SQLDataSource
1) Add a command field to your girdview columns
<asp:CommandField ButtonType="Button" EditText="Edit" ShowEditButton="true"/>
2) Add an update command to your data source
<asp:SqlDataSource ID="SqlDataSourceWS" runat="server"
ConnectionString="<%$ Connection String %>"
SelectCommand=" SELECT COMMAND HERE "
UpdateCommand=" UPDATE COMMAND HERE ">
<UpdateParameters>
<asp:Parameter Name="" />
<asp:Parameter Name="" />
</UpdateParameters>
</asp:SqlDataSource>
For more information on the command field and how to use it you can look at the Microsoft Developer Network Documentation
EDIT
Here is a very simple example of a SQLDatasource that shows how you may update an item
<asp:SqlDataSource ID="sqlMeetings" runat="server"
ConnectionString="<%$ connection %>"
SelectCommand="SELECT [meetingid]
,[groupname]
,[meetingtime]
,[meetingdate]
FROM [DCMS].[dbo].[tbl_meetings] "
UpdateCommand="UPDATE tbl_meetings
SET meetingdate = #meetingdate, meetingtime = #meetingtime
WHERE meetingid = #meetingid">
<UpdateParameters>
<asp:Parameter Name="meetingdate" />
<asp:Parameter Name="meetingtime" />
</UpdateParameters>
</asp:SqlDataSource>
From the example above you can see that I am selecting 3 fields from the data base but only allowing for two to be updated (meetingdate and meetingtime).
To edit the records, the GridView must enter EditMode. The grid changes modes according to the commands it receives, in this case "edit". See the remarks on the gridview page, 'Data Operations' section, for more info.
There are basically three ways to fire the command and enter edit mode on the grid:
Use the AutoGenerateEditButton property on the grid
Use a CommandField with ShowEditButton like the other answer stated
Use a custom TemplateField with a LinkButton inside like this:
<Columns>
...
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" Text="Edit" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton runat="server" Text="Update" CommandName="Update" />
<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" />
</EditItemTemplate>
</asp:TemplateField>
...
</Columns>
After that, it will depend on which DataSource control you are using. With an EntityDataSource, for instance, all you need to do is set EnableUpdate="true"
I'm using the BulkEditGridView control as discussed http://roohit.com/site/showArc.php?shid=bbb62, and it's perfect for my needs. The problem I'm having is that whenever I save, every visible row (I have paging enabled) gets updated. Stepping through the code I see that grid.DirtyRows.Count is equal to the number of items per page minus 1 when I click the save button.
I can't find where rows are set as dirty. Any suggestions where I can look?
My code-behind has only this:
using System;
using System.Web.UI.WebControls;
using System.Collections.Generic;
using System.Collections;
using System.Data.Common;
public partial class MSDS_MSDS_Admin_GridUpdate : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
gridMSDS.DataKeyNames = new String[] { "id" };
gridMSDS.DataBind();
}
}
}
EDIT: Here is the aspx code.
<%# Page Language="C#" MasterPageFile="~/MSDS/MSDS.master" AutoEventWireup="true" EnableEventValidation="false" CodeFile="GridUpdate.aspx.cs" Inherits="MSDS_MSDS_Admin_GridUpdate" Title="Untitled Page" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc1" %>
<%# Register Assembly="RealWorld.Grids" Namespace="RealWorld.Grids" TagPrefix="cc2" %>
<asp:Content ID="Content1" ContentPlaceHolderID="PageContent" runat="Server">
<br />
<asp:Button ID="btnSave" runat="server" Text="Save" Width="100%" />
<cc2:BulkEditGridView ID="gridMSDS" runat="server" AllowPaging="True" AllowSorting="True"
DataSourceID="sqlData" EnableInsert="False" InsertRowCount="1" PageSize="20"
SaveButtonID="btnSave" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" Visible="false"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="ChemicalTitle" HeaderText="ChemicalTitle" SortExpression="ChemicalTitle" />
<asp:TemplateField HeaderText="SheetDate" SortExpression="SheetDate">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("SheetDate") %>' Width="85px"></asp:TextBox>
<cc1:CalendarExtender ID="TextBox1_CalendarExtender" runat="server" Enabled="True"
TargetControlID="TextBox1">
</cc1:CalendarExtender>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("SheetDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Filename" HeaderText="Filename" SortExpression="Filename" />
<asp:BoundField DataField="Manufacturer" HeaderText="Manufacturer" SortExpression="Manufacturer" />
<asp:BoundField DataField="UsageDept" HeaderText="UsageDept" SortExpression="UsageDept" />
<asp:TemplateField HeaderText="Notes" SortExpression="Notes">
<EditItemTemplate>
<asp:TextBox ID="TextBox5" runat="server" Text='<%# Bind("Notes") %>' TextMode="MultiLine"></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label6" runat="server" Text='<%# Bind("Notes") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Status" SortExpression="Status">
<EditItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="sqlStatus" DataTextField="DisplayValue"
DataValueField="Value" SelectedValue='<%# Bind("Status") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="sqlStatus" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
SelectCommand="getOptionList" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="msds_Status" Name="ListName" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:DropDownList ID="ddlStatus" runat="server" DataSourceID="sqlStatus" disabled="true"
BackColor="White" DataTextField="DisplayValue" DataValueField="Value" SelectedValue='<%# Bind("Status") %>'>
</asp:DropDownList>
<asp:SqlDataSource ID="sqlStatus" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
SelectCommand="getOptionList" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter DefaultValue="msds_Status" Name="ListName" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Health" SortExpression="Health">
<EditItemTemplate>
<center>
<asp:TextBox ID="TextBox2" runat="server" Style="text-align: center" Text='<%# Bind("Health") %>'
Width="25px"></asp:TextBox>
</center>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Bind("Health") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Fire" SortExpression="Fire">
<EditItemTemplate>
<center>
<asp:TextBox ID="TextBox3" runat="server" Text='<%# Bind("Fire") %>' Width="25px"></asp:TextBox></center>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label4" runat="server" Text='<%# Bind("Fire") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Reactivity" SortExpression="Reactivity">
<EditItemTemplate>
<center>
<asp:TextBox ID="TextBox4" runat="server" Text='<%# Bind("Reactivity") %>' Width="25px"></asp:TextBox></center>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label5" runat="server" Text='<%# Bind("Reactivity") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="DateUpdated" HeaderText="DateUpdated" SortExpression="DateUpdated"
ReadOnly="True" />
<asp:BoundField DataField="UpdatedBy" ReadOnly="True" HeaderText="UpdatedBy" SortExpression="UpdatedBy" />
</Columns>
</cc2:BulkEditGridView>
<asp:SqlDataSource ID="sqlData" runat="server" ConnectionString="<%$ ConnectionStrings:NCLWebConnectionString %>"
SelectCommand="SELECT [ID], [ChemicalTitle], dbo.dateOnly([SheetDate]) As [SheetDate], [Filename], [Manufacturer], [UsageDept], [Notes], isnull([Status], 4) as [Status], [Health], [Fire], [Reactivity], [DateUpdated], [UpdatedBy] FROM [msds_Sheets] ORDER BY [ChemicalTitle]"
UpdateCommand="msds_UpdateSheet" UpdateCommandType="StoredProcedure">
<UpdateParameters>
<asp:Parameter Name="ID" Type="Int32" />
<asp:Parameter Name="ChemicalTitle" Type="String" />
<asp:Parameter Name="SheetDate" DbType="DateTime" />
<asp:Parameter Name="Filename" Type="String" />
<asp:Parameter Name="Manufacturer" Type="String" />
<asp:Parameter Name="UsageDept" Type="String" />
<asp:Parameter Name="Notes" Type="String" />
<asp:Parameter Name="Status" Type="Int16" />
<asp:Parameter Name="Health" Type="Int16" />
<asp:Parameter Name="Fire" Type="Int16" />
<asp:Parameter Name="Reactivity" Type="Int16" />
<asp:ProfileParameter Name="UpdatedBy" Type="String" PropertyName="Username" />
</UpdateParameters>
</asp:SqlDataSource>
</asp:Content>
Testing Procedure is as follows:
-Load the page.
-Edit something in the first row.
-Click save button.
The code you have posted looks fine. My test code is almost identical to yours, but I cannot produce the unwanted results you are seeing.
The most significant difference between your code and mine is that I don't have the code for your master page. My master page is the default page created by VS 2008. Other than that, the differences are in the SQL and the underlying database. Specifically, I am not using any stored procedures, and I have made reasonable assumptions about the data types involved: the ID is int, Status is smallint, SheetDate is Date, DateUpdated is DateTime, and everything else is varchar.
EDIT: Your SheetDate appears to be just the date portion of an underlying DateTime value from the database. The fact that your query transforms the underlying data value for display purposes is not relevant, because the grid view can't tell that it is getting a modified value. END OF EDIT
Here are a few suggestions for diagnosing the problem:
Test without master page, or with a
very simple dummy master page that is
guaranteed not to have scripts that
interact with the BulkEditGridView.
Since the ToolkitScriptManager is
apparently on your master page, you will
need to either move the script
manager control to the page itself,
or else temporarily get rid of the
CalendarExtender element, which
requires the script manager.
Temporarily replace the Status
template field with a bound data
field, to eliminate possibility of
interaction with the DropDownList.
The drop down list did not cause
problems in my tests, but there may
be subtle differences between your
code and mine.
If neither of these help, then a possible cause is a problem in your
version of the BulkEditGridView.
EDIT - Additional suggestions for diagnosis:
Based on examination of the source code for BulkEditGridView, it appears that the code is properly tracking which rows of the grid are "dirty". Therefore, the most likely cause of a spurious dirty row is that one or more controls in the grid are incorrectly detecting a change to their data content. You can detect this in the debugger, using the source code for BulkEditGridView, rather than the pre-compiled DLL.
Set a breakpoint at the start of HandleRowChanged, the event handler which detects changes in any cell of the grid. By examining the sender parameter of that object in the debugger, you can tell which controls in the grid are undergoing value changes. In particular, you will be able to tell which controls, if any, are incorrectly triggering a value change event.
Once you determine which control(s) are incorrectly reporting that their value has changed, you can focus on why this is happening.
END OF EDIT
Some other suggestions to improve the code are as follows. These will not solve the original problem, but will make the code cleaner:
In all of the template fields, remove the ItemTemplates. They can never be used, since the BulkEditGridView forces every row to be in the edit state.
In the code behind, the BindData()
call is not needed, since the source
data is specified in the declarative
markup, and therefore the grid view
control will automatically bind the
data.
I am not an expert in BulkEditGridView control, but this is what I found at Matt Dotson's blog entry
You may not be able to know that the row has been updated, unless you watch for the change explicitly. First, for each row add a change handler
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);
}
}
}
You can use this snippet
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);
}
}
}
Then you define a dirty row list and add rows that needs to be updated there (in the event handler)
private List<int> dirtyRows = new List<int>();
void HandleRowChanged(object sender, EventArgs args)
{
GridViewRow row = ((Control) sender).NamingContainer as GridViewRow;
if (null != row && !dirtyRows.Contains(row.RowIndex))
{
dirtyRows.Add(row.RowIndex);
}
}
Finally, to commit changes, iterate through all the dirty rows and save changes
public void Save()
{
foreach (int row in dirtyRows)
{
this.UpdateRow(row, false);
}
dirtyRows.Clear();
}
And here is your ASPX code
<asp:Button runat="server" ID="SaveButton" Text="Save Data" />
<blog:BulkEditGridView runat="server" id="EditableGrid" DataSourceID="AdventureWorks" AutoGenerateColumns="False" DataKeyNames="LocationID" SaveButtonID="SaveButton" >
<Columns>
<asp:BoundField DataField="LocationID" HeaderText="LocationID" InsertVisible="False" ReadOnly="True" SortExpression="LocationID" />
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name" />
<asp:BoundField DataField="Availability" HeaderText="Availability" SortExpression="Availability" />
<asp:BoundField DataField="CostRate" HeaderText="CostRate" SortExpression="CostRate" />
</Columns>
</blog:BulkEditGridView>