ObjectDataSource could not find a non-generic method that has parameters: - asp.net

I'm trying to use a Gridview to show a datatable from an Object data source. It's giving me the error:
ObjectDataSource 'odsStores' could not find a non-generic method 'ProcessDelete' that has parameters: ProcessID.
I've read a lot of other answers to this question about matching case, matching format, variables but I think I've done all of those correctly. Here's the aspx page:
<asp:GridView ID="gridStores" runat="server" AllowSorting="False" AutoGenerateColumns="False"
CssClass="grid-main" DataSourceID="odsStores" EnableViewState="False" OnDataBound="gridStores_DataBound"
OnRowDataBound="gridStores_RowDataBound">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:Image ID="imgModel" runat="server" AlternateText="Click to See Details" CssClass="img-details"
EnableViewState="False" ImageUrl="~/img/detail.gif" />
</ItemTemplate>
<ItemStyle CssClass="grid-main-detail" />
</asp:TemplateField>
<asp:BoundField DataField="ProcessID" HeaderText="ProcessID" />
<asp:BoundField DataField="ProcessName" HeaderText="Process Name" ReadOnly="False" />
<asp:BoundField DataField="ProcessDescription" HeaderText="Process Description" ReadOnly="False" />
<asp:BoundField DataField="UpdateUserID" HeaderText="Last Updated By" ReadOnly="True" />
<asp:BoundField DataField="UpdateTimestamp" HeaderText="Last Updated" ReadOnly="True" />
<asp:CommandField ShowEditButton="True" />
<asp:CommandField ShowDeleteButton="True" />
</Columns>
</asp:GridView>
Here's the code behind, all I have is a break point and it never hits it.
<DataObjectMethod(DataObjectMethodType.Delete)> _
Private Sub ProcessDelete(ByVal ProcessID As String)
Dim x As Integer = 0
x = x + 1
End Sub
Here's the object datasource:
<asp:ObjectDataSource ID="odsStores" runat="server" EnableViewState="False" OldValuesParameterFormatString="original_{0}"
SelectCountMethod="GetRowCount" SelectMethod="GetData" TypeName="DataWarehouseUserInterface.ProcessBSL"
UpdateMethod="ProcessUpdate" DeleteMethod="ProcessDelete" >
<UpdateParameters>
<asp:FormParameter Name="ProcessName" Type="String" FormField="ProcessName" />
<asp:FormParameter Name="ProcessDescription" Type="String" FormField="ProcessDescription" />
</UpdateParameters>
<DeleteParameters>
<asp:FormParameter Name="ProcessID" Type="String"/>
</DeleteParameters>
</asp:ObjectDataSource>

My Object data source was looking in my ProcessBSL for a method called ProcessDelete with the corresponding signature. I had written my methods in the code behind ProcessBSL file.
This was the line of code that effected it:
TypeName="DataWarehouseUserInterface.ProcessBSL"
Summary:
If it's throwing this error for you, ensure your method signature is correct. Ensure that the BSL layer is correct. Make sure you have _ - that also stopped mine from working. Hope this helps someone else.
Cheers.

Try making the method public to see if that works.

Related

How to add a 'Record Deleted' message in this code?

I want to add a Record Delete Message when the Delete button is selected. The message would appear for 5 seconds, then disappear. Here's the code:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AllowSorting="True" DataSourceID="SqlDataSource1"
AutoGenerateColumns="False" DataKeyNames="ScheduleId">
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField DataField="SDate" HeaderText="SDate" SortExpression="SDate" />
<asp:BoundField DataField="STime" HeaderText="STime" SortExpression="STime" />
<asp:BoundField DataField="SNoPlaces" HeaderText="SNoPlaces"
SortExpression="SNoPlaces" />
<asp:BoundField DataField="ScheduleId" HeaderText="ScheduleId"
InsertVisible="False" ReadOnly="True" SortExpression="ScheduleId" Visible="false" />
<asp:BoundField DataField="STourId" HeaderText="STourId" SortExpression="STourId" Visible="false" />
<asp:BoundField DataField="TName" HeaderText="Tour Name" SortExpression="TName" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ChinatowndbConnString %>"
DeleteCommand="DELETE FROM Schedule WHERE (ScheduleId = #ScheduleId)"
SelectCommand="SELECT SDate, STime, SNoPlaces, ScheduleId, STourId, TName FROM Schedule INNER JOIN Tour ON Schedule.STourId = Tour.TourId">
<DeleteParameters>
<asp:Parameter Name="ScheduleId" />
</DeleteParameters>
</asp:SqlDataSource>
Regards
Tea
Use this gridview event:
protected void GridView1_RowDeleted(object sender, GridViewDeletedEventArgs e)
{
LabelMsg.Text = "Record Deleted";
}
I would use jQuery to always Fadeout the LabelMsg element on $(document).ready(). So no matter what you put in it, from the server side, it will fade out in the time you decide.
I don't think you can accomplish this naively as part of a GridView but you can wire up the RowDeleted event to inject some JavaScript using the ClientScriptManager.RegisterStartupScript method.
I would suggest using toastr to display your actual message and it can be added to your project with its associated nuget package.
RowDeleted
RegisterStartupScript
toastr

Must Declare Scalar Variable when it is already defined, and Sytax error near 'nvarchar' when updating

Solution at the bottom.
I receive the following error when trying to update records:
Must declare Scalar Variable #PaymentTermID
Problem is, #PaymentTermID should be defined already in the Update parameters. The 2 functions for onrowdatabound and onrowupdate are tweaked versions of the ones found here for the DropDownList: GridViewRow.DataItem Property. Delete works fine.
No new lines are added, just names changed around. Any help would be appreciated, I am not exactly used to working with asp objects.
<asp:GridView ID="GridView1" onrowdatabound="GridView1_RowDataBound" onrowupdating="GridView1_RowUpdating" runat="server" AutoGenerateColumns="False" DataKeyNames="PaymentTermID" DataSourceID="SqlDataSource1" CellPadding="1" CellSpacing="2">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:TemplateField HeaderText="Key Contract Date" SortExpression="Key Contract Date">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource2" DataTextField="Key_Contract_Date" DataValueField="Key_Contract_Date" />
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:Production_DatabaseConnectionString %>"
SelectCommand="SELECT DISTINCT [Key Contract Date] AS Key_Contract_Date FROM [tblPRJ_PaymentTerms]" />
</EditItemTemplate>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("[Key Contract Date]") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Due Date" HeaderText="Due Date" SortExpression="Due Date" />
<asp:BoundField DataField="Percent Due" HeaderText="Percent Due" SortExpression="Percent Due" />
<asp:BoundField DataField="Custom Description" HeaderText="Custom Description" SortExpression="Custom Description" />
</Columns>
<HeaderStyle Font-Bold="True" ForeColor="#666666" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Production_DatabaseConnectionString %>"
SelectCommand="SELECT * FROM [tblPRJ_PaymentTerms] WHERE ([Job Number] = #Job_Number)"
DeleteCommand="DELETE FROM [tblPRJ_PaymentTerms] WHERE [PaymentTermID] = #PaymentTermID"
InsertCommand="INSERT INTO [tblPRJ_PaymentTerms] ([Job Number], [Key Contract Date], [Due Date], [Percent Due], [Custom Description]) VALUES (#Job_Number, #Key_Contract_Date, #Due_Date, #Percent_Due, #Custom_Description)"
UpdateCommand="UPDATE [tblPRJ_PaymentTerms] SET [Job Number] = #Job_Number, [Key Contract Date] = #Key_Contract_Date, [Due Date] = #Due_Date, [Percent Due] = #Percent_Due, [Custom Description] = #Custom_Description WHERE [PaymentTermID] = #PaymentTermID">
<DeleteParameters>
<asp:Parameter Name="PaymentTermID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="Job_Number" Type="String" />
<asp:Parameter Name="Key_Contract_Date" Type="String" />
<asp:Parameter Name="Due_Date" Type="DateTime" />
<asp:Parameter Name="Percent_Due" Type="Decimal" />
<asp:Parameter Name="Custom_Description" Type="String" />
</InsertParameters>
<SelectParameters>
<asp:ControlParameter ControlID="txtCurrentJobNumber" Name="Job_Number" PropertyName="Text" Type="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="Job_Number" Type="String" />
<asp:Parameter Name="Key_Contract_Date" Type="String" />
<asp:Parameter Name="Due_Date" Type="DateTime" />
<asp:Parameter Name="Percent_Due" Type="Decimal" />
<asp:Parameter Name="Custom_Description" Type="String" />
<asp:Parameter Name="PaymentTermID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
SOLUTION: There were multiple problems happening here. First and foremost, GuthMD was correct in his assessment of parameters needing a reference in terms of either a boundfield, templatefield, or other source (such as a control in the case of a control parameter). Simply creating an asp:boundfield for the PaymentTermID and setting the Visible property to false fixed the problem I posted about.
The other problem was that the database was setup poorly, and had spaces in column names. The OLEDB driver doesn't like that, and causes errors when you try to write back to the database and you have spaces in column names (even if it's encased in brackets []). After fixing the names in SQL, then revisiting our code and rewriting most of the SQL code for it, things started behaving as expected.
Thanks again for your help.
I've been looking through the MSDN documentation for Using Parameters, and it seems that for the binding to be created between the GridView and your SqlDataSource that your GridView is going to need to have BoundField elements corresponding to the Parameter elements.
Add the following to the <Columns> of your GridView:
<asp:BoundField DataField="Job_Number" Visible="false" />
<asp:BoundField DataField="Key_Contract_Date" Visible="false" />
<asp:BoundField DataField="Due_Date" Visible="false" />
<asp:BoundField DataField="Percent_Due" Visible="false" />
<asp:BoundField DataField="Custom_Description" Visible="false" />
<asp:BoundField DataField="PaymentTermID" Visible="false" />
1-The problem occurs when datasource is OleDb not SQLclient.
Change the DataSource1 to :
providerName="System.Data.SqlClient"
2-Make sure valid binding field in grid definition DataKeyNames="id_field"

How to use GridView edit functionality to modify a field that relies on another field

Sorry for the convoluted title, but that is the best way I could think to phrase it.
Basically, I have a column of data that is a URL (lets call it URL-A), and another that is hidden which is also a URL(URL-B). I have a function called ConvertURL(string URLin) in the codebehind that will take URL-A and turn it into URL-B.
So in this gridview, if someone were to edit an entry using the native gridview/datasource functionality and change URL-A, how do I get it to run this new URL-A through ConvertURL() and update the URL-B field?
Here is a simple representation of the code (not the actual code):
Code-behind function:
public string ConvertURL(string URLin)
{
Int32 iLocation = URLin.IndexOf("WWW.XYZ.COM");
if (iLocation >= 0)
{
string checkurl = URLin.Replace("WWW.XYZ.COM", "STAGING.XYZ.COM");
return checkurl;
}
else
{
return URLin;
}
}
Data-Source:
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:My_AppConnectionString %>"
SelectCommand="SELECT [URL_A], [URL_B], [URLName] FROM [My_App] WHERE ([IsActive] = #IsActive)"
OldValuesParameterFormatString="original_{0}"
UpdateCommand="UPDATE [My_App] SET [URL_A] = #URL_A, [URL_B] = #URL_B, [URLName] = #URLName, [IsActive] = #IsActive WHERE [ID] = #original_ID">
<SelectParameters>
<asp:Parameter DefaultValue="True" Name="IsActive" Type="Boolean" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="URL_A" Type="String" />
<asp:Parameter Name="URL_B" Type="String" />
<asp:Parameter Name="URLName" Type="String" />
<asp:Parameter Name="IsActive" Type="boolean" />
<asp:Parameter Name="original_ID" Type="Int32" />
<asp:Parameter Name="original_URL_A" Type="String" />
<asp:Parameter Name="original_URL_B" Type="String" />
<asp:Parameter Name="original_URLName" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
And Lastly the GridView:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
onrowediting="GridView1_RowEditing"
AutoGenerateColumns="False" CellPadding="3" DataKeyNames="ID"
DataSourceID="SqlDataSource1" EnableModelValidation="False" ForeColor="Black"
GridLines="Vertical" AllowSorting="True" BackColor="White"
BorderColor="#999999" BorderStyle="Solid" BorderWidth="1px"
AutoGenerateEditButton="True" CausesValidation="false">
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" Visible="False" />
<asp:BoundField DataField="URL_A" HeaderText="URL A"
SortExpression="URL_A" />
<asp:BoundField DataField="URL_B" HeaderText="URL B"
SortExpression="URL_B" **Visible="False"** />
<asp:BoundField DataField="URLName" HeaderText="URL Name"
SortExpression="URLName" />
<asp:CheckBoxField DataField="IsActive" HeaderText="Active"
SortExpression="IsActive" />
</Columns>
<FooterStyle BackColor="#CCCCCC" />
<HeaderStyle BackColor="Black" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#000099" Font-Bold="True" ForeColor="White" />
</asp:GridView>
So to summarize: A user will see a gridview with 3 fields to edit, one of which is URL_A (URL_B is hidden). When they hit edit and update the URL_A field I want to run URL_A through the ConvertURL() function and use that output as the data for URL_B when the update is performed.
I appreciate the help in advance!
Use the RowUpdating event of the grid view and change the new value for URL_B. In that event you will have access to the old values of the row as well as the new values. You can change the new values before they are sent to the data source for the actual update.
Add the event handler to the grid view in the ASPX:
<asp:GridView ID="GridView1" runat="server"
...
OnRowUpdating="GridView1_RowUpdating">
And in the code file handle the event:
protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
// Find the current value for URL_A
string urlA = (string)e.NewValues["URL_A"];
// Get the corresponding value for URL_B from the method
string urlB = ConvertURL(urlA);
// Set the new value for the URL_B column before it's sent to the SqlDataSource
e.NewValues["URL_B"] = urlB;
}

Avoid duplicate data when using asp:control to insert

I have a ASP.NET code, I use it to insert and view my data from a *.mdb file.
When I reload the browser reload, it insert the same old data.
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False"
DataKeyNames="user_id" DataSourceID="AccessDataSource1" Height="50px"
Width="125px" DefaultMode="Insert">
<Fields>
<asp:BoundField DataField="user_id" HeaderText="user_id" InsertVisible="False"
ReadOnly="True" SortExpression="user_id" />
<asp:BoundField DataField="user_name" HeaderText="user_name"
SortExpression="user_name" />
<asp:BoundField DataField="user_pass" HeaderText="user_pass"
SortExpression="user_pass" />
<asp:BoundField DataField="user_email" HeaderText="user_email"
SortExpression="user_email" />
<asp:CommandField ButtonType="Button" ShowInsertButton="True" />
</Fields>
</asp:DetailsView>
<div ID="Div1" runat="server"></div>
<asp:AccessDataSource ID="AccessDataSource1" runat="server"
DataFile="~/App_Data/esn.mdb"
SelectCommand="SELECT * FROM [user]"
InsertCommand="INSERT INTO [user] ([user_name], [user_pass], [user_email]) VALUES (#user_name, #user_pass, #user_email)">
<InsertParameters>
<asp:Parameter Name="user_name" Type="String" />
<asp:Parameter Name="user_pass" Type="String" />
<asp:Parameter Name="user_email" Type="String" />
</InsertParameters>
</asp:AccessDataSource>
<asp:GridView ID="GridView1" runat="server"
AutoGenerateColumns="False" DataKeyNames="user_id"
DataSourceID="AccessDataSource1">
<Columns>
<asp:BoundField DataField="user_id" HeaderText="user_id" InsertVisible="False"
ReadOnly="True" SortExpression="user_id" />
<asp:BoundField DataField="user_name" HeaderText="user_name"
SortExpression="user_name" />
<asp:BoundField DataField="user_pass" HeaderText="user_pass"
SortExpression="user_pass" />
<asp:BoundField DataField="user_email" HeaderText="user_email"
SortExpression="user_email" />
</Columns>
</asp:GridView>
</form>
I think sendig user to a success insert page is an option!
Try look here:
detect duplicate insert
or here:
ASP.Net - Prevent Duplicate(Double) Inserts when Page is refreshed
How to Prevent Duplicate Record Insertion on Refresh Click in Browser in ASP.Net ?
Here a Microsoft article:
Trap the Browser Refresh
use viewstate or session to store a flag "hasSaved". when the page loads for the first time :
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
ViewState["hasSaved"] = false;
}
and change the value of "hasSaved" to true when the the data is saved note that save the value if "hasSaved" is false
See the full code here
Avoid Repeated insertion due to page refresh

Using <asp:EntityDataSource>

I am using EntityDataSource control to display Data in Grid, I want to use the same EntityDataSource to display all data as well as per the search, the problem is I can do only one thing either can use it to search or to get whole data
here is my .aspx page
<asp:EntityDataSource ID="InvestorsSource" runat="server"
ConnectionString="name=Entities"
DefaultContainerName="Entities" EnableFlattening="False"
EntitySetName="Investors" EntityTypeFilter="Investor"
Select="it.[InvestorId], it.[InvestorName], it.[Summary], it.[Logo], it.[EmailAddress], it.[PhoneNumber], it.[Website]"
AutoGenerateWhereClause="True" OrderBy="it.[InvestorName]">
<WhereParameters>
<asp:FormParameter FormField="txtSearchInvestor" Name="investorName" Type="String" />
</WhereParameters>
</asp:EntityDataSource>
<asp:TextBox ID="txtSearchInvestor" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server" Text="Go" onclick="Button1_Click" />
<p>
<asp:GridView ID="gvInvestors" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False"
DataSourceID="InvestorsSource">
<Columns>
<asp:BoundField DataField="InvestorId" HeaderText="InvestorId" ReadOnly="True"
SortExpression="InvestorId" />
<asp:BoundField DataField="InvestorName" HeaderText="InvestorName"
SortExpression="InvestorName" ReadOnly="True" />
<asp:BoundField DataField="Summary" HeaderText="Summary"
SortExpression="Summary" ReadOnly="True" />
<asp:BoundField DataField="EmailAddress" HeaderText="EmailAddress"
SortExpression="EmailAddress" ReadOnly="True" />
<asp:BoundField DataField="PhoneNumber" HeaderText="PhoneNumber"
SortExpression="PhoneNumber" ReadOnly="True" />
<asp:BoundField DataField="Website" HeaderText="Website"
SortExpression="Website" ReadOnly="True" />
</Columns>
</asp:GridView>
</p>
Thanks
I setup a page using the Northwind DB and using the Employees table. There is a TextBox control and Button controls just like your code to filter the data. When the TextBox is empty, all records are displayed. When a EmployeeID is entered into the TextBox, and the 'Filter' button is clicked, only the employee with the EmployeeID is displayed(if present in the data). I think this is the kind of behavior you are asking for. Here is the markup:
<form id="form1" runat="server">
<div>
<asp:EntityDataSource ID="EntityDataSource1" runat="server"
ConnectionString="name=NWEntities" DefaultContainerName="NWEntities"
EntitySetName="EmployeeSet" EntityTypeFilter="Employee" AutoGenerateWhereClause="true"
Select="it.[EmployeeID], it.[LastName], it.[FirstName], it.[Title], it.[TitleOfCourtesy], it.[BirthDate]">
<WhereParameters>
<asp:FormParameter FormField="txtFilter" Name="EmployeeID" Type="Int32" />
</WhereParameters>
</asp:EntityDataSource>
<asp:TextBox ID="txtFilter" runat="server" />
<asp:Button runat="server" Text="Filter" />
<asp:GridView ID="gvEmployees" runat="server" DataSourceID="EntityDataSource1" AutoGenerateColumns="true" />
</div>
</form>
Edit: The question has been raised as how part of a value could be entered into the filter text box to get all the values that start with the entered value. You could use the LIKE SQL operator and the users would need to be told that the "%" character is the wildcard. I changed the filter to the FirstName field. Here are the changes to the above code:
In the EntityDataSource tag:
AutoGenerateWhereClause="false"
Where="it.[FirstName] LIKE #FirstName"
In the WhereParameters tag:
<asp:FormParameter FormField="txtFilter" Name="FirstName" Type="String" DefaultValue="%" />
Now, when "n%" is entered into the filter textbox, all records with a FirstName value that starts with "n" will be displayed. Any valid LIKE clause could now be used.

Resources