ObjectDataSource can not find control parameter sometimes - c#

I have a formview that is populated with an ObjectDataSource and it works great. Nested in that is a gridview also populated with a nested ODS that works perfect 99% of the time. Also nested in the formview is another ODS populated from the same control that populates the other nested datasource that works perfect all of the time. Code below to make that make sense.
The problem is if you change pages it all works fine most of the time. There are 2 search features built into the page. That is where the error occurs. If you use either of them without changing pages it works great. If you use one of them and then change pages and try to use either one of them the page crashes with an error that says something like Control Parameter 'X' is not found in 'Y'. The problem is that it is not a true error because there is a button that displays the bootstrap model which displays its gridview with no issues and the ODS is based on exactly the same control so it is obviously there. I imagine that it is related to the events, but they step through just fine. I am not sure what could be causing it.
Here is a little test project that is basically the same setup only paging is setup in the formview and the ODS1 in the real project and it works perfectly.
<asp:FormView ID="FormView1" runat="server" DataSourceID="ObjectDataSource1">
<ItemTemplate>
ImportantID:
<asp:Label Text='<%# Bind("ImportantID") %>' runat="server" ID="ImportantIDLabel" Visible="false" /><br />
Name:
<asp:Label Text='<%# Bind("Name") %>' runat="server" ID="NameLabel" /><br />
<div id="nestedContent">
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server" SelectMethod="listNested" TypeName="TestProject.DataSourceClass">
<SelectParameters>
<asp:ControlParameter ControlID="ImportantIDLabel" PropertyName="Text" DefaultValue="-1" Name="ImportantIDFromOnject1ForNestedObject" Type="Int32"></asp:ControlParameter>
</SelectParameters>
</asp:ObjectDataSource>
<asp:GridView ID="GridView1" runat="server" DataSourceID="ObjectDataSource2" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="YetAnotherProperty" HeaderText="YetAnotherProperty" SortExpression="YetAnotherProperty"></asp:BoundField>
<asp:BoundField DataField="OtherPropertiesGoInThisClass" HeaderText="OtherPropertiesGoInThisClass" SortExpression="OtherPropertiesGoInThisClass"></asp:BoundField>
</Columns>
</asp:GridView>
</div>
SomeProperty:
<asp:Label Text='<%# Bind("SomeProperty") %>' runat="server" ID="SomePropertyLabel" /><br />
SomeOtherProperty:
<asp:Label Text='<%# Bind("SomeOtherProperty") %>' runat="server" ID="SomeOtherPropertyLabel" /><br />
<asp:ObjectDataSource ID="ObjectDataSource3" runat="server" SelectMethod="GetDataObject2" TypeName="TestProject.DataSourceClass">
<SelectParameters>
<asp:ControlParameter ControlID="ImportantIDLabel" PropertyName="Text" DefaultValue="-1" Name="ImportantID" Type="Int32"></asp:ControlParameter>
</SelectParameters>
</asp:ObjectDataSource>
<div id="BootStrapModalPopup">
This displays the data with no problems
</div>
</ItemTemplate>
</asp:FormView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetDataObject1" TypeName="TestProject.DataSourceClass">
<SelectParameters>
<asp:Parameter DefaultValue="-1" Name="ImportantID" Type="Int32"></asp:Parameter>
<asp:Parameter DefaultValue="" Name="Name" Type="String"></asp:Parameter>
<asp:Parameter Name="SomeProperty" Type="String"></asp:Parameter>
</SelectParameters>
</asp:ObjectDataSource>
I would appreciate any ideas of where to look next. By the way I have used a textbox, hiddencontrol and Session variable for the ID field and nothing makes a difference for it. If I disable the ODS2 it goes back to working perfectly also but I need that data.
Thanks
Jimmy

I actually lucked into the answer for this. It was not my nesting it was my paging. I will leave the question for anyone that has a similar problem since I don't see any successful errors to this. The issue I faced was I needed to reset my pageindex on search. It worked great searching from page one, but searching from any other page is an empty return due to the indexing so the controls did not exist. Hopefully it will help someone to search that if you run into this issue. Just set pageindex on the formview back to 0.

Related

Date fomat issue using UpdateCommand in ASP.NET

I'm using ASP.NET (C#), MySQL.
I'm trying to use a FormView component feed by a SQLDataSource ... the goal is to create a form to handle data from a single table without too much coding and relying on the framework as much as I can.
I found how to show data and to edit them but when I come to 'date' fields I found an early stop in my mission.
Since I'm italian I use a standard 'italian' date format (dd/MM/yyyy) that's quite different from MySQL internal date format (yyyy-MM-dd) this lead to a date format error when I try to update fields.
The form which include the 'date' field is defined this way:
<asp:FormView
ID="_frmData"
runat="server"
DataKeyNames="id"
DataSourceID="_sdsContatto"
DefaultMode="Edit">
<EditItemTemplate>
<asp:Table runat="server">
<asp:TableRow>
<asp:TableCell>
<asp:TextBox
ID="_txtDate"
runat="server"
Text='<%#Bind("date_field","{0:dd/MM/yyyy}")%>' />
</asp:TableCell>
</asp:TableRow>
</asp:Table>
</EditItemTemplate>
</asp:FormView>
The SQLDataSource is defined this way:
<asp:SqlDataSource ID="_sdsData
runat="server"
ConnectionString="<%$ ConnectionStrings:data_db %>"
ProviderName="<%$ ConnectionStrings:data_db.ProviderName %>"
SelectCommand=" SELECT
date_field
FROM
table
WHERE
id=#id;"
UpdateCommand=" UPDATE
table
SET
date_field = #date_value
WHERE
id=#id;">
</asp:SqlDataSource>
Using the 'italian' date format lead to this error:
Incorrect date value: '9/12/1971' for column 'date_field' at row 1
There's a way to fix this type of problem ?
I tried with MySQL STR_TO_DATE() without luck.
Best Regards for any help or suggestion.
Mike
The solution relay into 'separate' visualization from data submission. To cut it short the best way to ovveride such problems is this one:
<asp:FormView
ID="_fvData"
runat="server"
DataKeyNames="id"
DataSourceID="_sdsTable1"
DefaultMode="Insert" Width="100%">
<InsertItemTemplate>
<asp:TextBox
ID="_txtDate"
runat="server"
Text='<%#Eval("date_field","{0:dd/MM/yyyy}")%>' />
</InsertItemTemplate>
</asp:FormView>
In the sqldatasource (either in InsertParameters or UpdateParameters sections) the we need to reference the field trough a ControlParameter entry, in this way:
<asp:SqlDataSource
ID="_sdsTable1"
runat="server"
InsertCommandType="StoredProcedure"
InsertCommand="create_table1">
<InsertParameters>
<asp:ControlParameter
Name="date_field"
ConvertEmptyStringToNull="true"
Type="DateTime"
ControlID="_fvData$_txtDate"
PropertyName="Text" />
</InsertParameters>
</asp:SqlDataSource>

Bind asp:Parameter in asp:SqlDataSource to Database field

I use an asp:SqlDataSource Element to fetch Data and then display it in an asp:ListView.
For the sake of simplicity, let's assume the Database consists of the rows and id, author (it's actually more, but that doesn't matter).
This is the code I use:
<asp:SqlDataSource ID="NewsDataSource" runat="server"
ConnectionString="<%$ connectionStrings:RemoteSqlConnection %>"
ProviderName="System.Data.SqlClient"
SelectCommand="SELECT * FROM [news]"
UpdateCommand="UPDATE [news] SET author=#author WHERE id=#id"
DeleteCommand="DELETE FROM [news] WHERE id=#id"
InsertCommand="INSERT INTO [news] (author) VALUES (#author)">
<UpdateParameters>
<asp:Parameter Name="id" Type="Int32" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="id" Type="Int32" />
</DeleteParameters>
</asp:SqlDataSource>
My problem is, that the parameter id which I define for UpdateParameters and DeleteParameters is always null.
It doesn't seem to be associated with the database field id.
One hack which allowed me to fix the problem (but only for the update case) was to insert an invisible asp:Label to which I binded the id (Just like I binded the Author field to a Textbox).
I don't think that the ListView code should be relevant, but I'll try to include some lines which are relevant here:
<asp:ListView runat="server" DataSourceID="NewsDataSource">
<LayoutTemplate>
<div id="itemPlaceholder" runat="server"></div>
</LayoutTemplate>
<ItemTemplate>
<%# Eval("author")%>
</ItemTemplate>
<EditItemTemplate>
<!-- This line is only the workaround solution --><asp:Label ID="idLabel" runat="server" Text='<%# Bind("id")%>'></asp:Label>
<asp:TextBox ID="authorTextbox" runat="server" Text='<%# Bind("author")%>'></asp:TextBox>
</EditItemTemplate>
</asp:ListView>
There is an attribute on the asp:ListView called DataKeyNames, adding id to this should make it store that parameter value without the need for a hidden element.
For more information on the DataKeyNames attribute see: http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.datakeynames(v=vs.110).aspx

How to pass a URL parameter to a ObjectDataSource SelectMethod?

I have a small example application with articles and comments.
Users can view a specific Article by passing the article ID value in URL:
http://localhost:56079/viewArticle.aspx?id=123456
I want the Article id to be used to find corresponding comments and populate a gridview with them in the same form.
viewArticle.aspx:
<dx:ASPxGridView ID="ASPxGridView1" runat="server" AutoGenerateColumns="False" Width="100%" DataSourceID="ObjectDataSource1">
<Columns>
<dx:GridViewDataTextColumn FieldName="field1" Caption="Field #1" VisibleIndex="0" />
<dx:GridViewDataTextColumn FieldName="field2" Caption="Field #2" VisibleIndex="1" />
</Columns>
</dx:ASPxGridView>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="searchComments"
TypeName="App.CommentManager">
<SelectParameters>
</SelectParameters>
</asp:ObjectDataSource>
If id is "hard-coded" in the searchComments method, gridview is populated with correct entries.
My only problem is passing the article id to searchComments method.
I was thinking about a <%# %>" style databinding approach, but it would be extremely dirty, and it still doesn't work.
SelectMethod="searchComments(<%# Request.QueryString["id"] %>)"
Another approach I tried was setting the selectmethod in codebehind like this:
ObjectDataSource1.SelectMethod = "searchComments('123456')";
That results in error: ObjectDataSource 'ObjectDataSource1' could not find a non-generic method 'searchComments('123456')' that has no parameters.
Pass a QueryStringParameter directly into SelectParameters - ie:
<SelectParameters>
<asp:QueryStringParameter QueryStringField="id" />
</SelectParameters>
You can use QueryStringParameter in SelectParameters section
<SelectParameters>
<asp:QueryStringParameter QueryStringField="id" Name="id"/>
</SelectParameters>

Get updated query results on page

I have an asp.net intranet site hosted on IIS on my computer.
On one page you can enter two user id's and get a side by side comparison of their roles in our (custom app) system.
I often use it to add roles when I'm setting up new users. After running the query, if i change a role and run the query again it will not show updated results. It's being cached somehow. I have to go to another page and come back and them run the query to get updated results.
How can avoid having to navigate away to get the updated query results displayed.n
here's the code
<asp:Label ID="Label1" runat="server" Text="Username"></asp:Label>
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<br />
<asp:Label ID="Label2" runat="server" Text="Username"></asp:Label>
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
<asp:Button ID="Button1" runat="server"
Text="Compare Permissions" />
<br /><br />
<asp:GridView ID="GridView1" runat="server" CssClass="mGrid" DataSourceID="SqlDataSource1">
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
ProviderName="<%$ ConnectionStrings:ConnectionString.ProviderName %>" SelectCommand="WITH
firstPerson AS
(
select username, security_role from user_role
where username=upper(:Username1)
),
secondPerson as
(
select username, security_role from user_role
where username=upper(:UserName2)
)
select firstPerson.username , firstPerson.security_role,secondPerson.username,secondPerson.security_role from firstPerson FULL JOIN secondPerson
on firstPerson.security_role=secondPerson.security_role order by firstPerson.security_role, secondPerson.Security_role">
<SelectParameters>
<asp:ControlParameter ControlID="TextBox1" Name="Username1"
PropertyName="Text" />
<asp:ControlParameter ControlID="TextBox2" Name="UserName2"
PropertyName="Text" />
</SelectParameters>
</asp:SqlDataSource>
I think the problem is simply that after you add these new values, you are not refreshing your gridview. There aren't any controls that can "automagically realize" the data has changed. Instead, you need to do it manually, by rebinding your data view control to it's (new) data with DataBind().
Check where you are getting your data.
If you have it in an if statement like
if(!IsPostBack)
That means you will only get the data when you first run. When you are navigate away and then back you are loading the page again for the first time.

updating a gridview always returns null parameters

I have a simple gridview (well it is now) it populates, I can edit it. but when it comes to updating I just cant get it to work.
The following code creates a gridview which searches for users whose name starts with a "c" (Thats part of my filtering I stripped out)
The problem is when I click the update button it won't update. The Stored procedure gets called but all parameters passed to it are null. therefore the database is not updated.
I know its a simple problem with a simple solution but I just can't see it.
I tried using ExtractValuesFromCell within the onupdating event and still only got nulls. I had to add the CausesValidation="false" because without it the update events were not even called.
Any and all help is appreciated
<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
AutoGenerateColumns="False" DataSourceID="SqlDataSource3"
DataKeyNames="UserId">
<Columns>
<asp:CommandField ShowEditButton="True" CausesValidation="false" />
<asp:BoundField DataField="UserName" HeaderText="UserName"
SortExpression="UserName" />
<asp:BoundField DataField="MobileAlias" HeaderText="MobileAlias"
SortExpression="MobileAlias" />
<asp:BoundField DataField="DistrictId" HeaderText="DistrictId"
SortExpression="DistrictId" />
<asp:BoundField ReadOnly="true" DataField="UserId" HeaderText="UserId"
SortExpression="UserId" />
</Columns>
</asp:GridView> <asp:SqlDataSource ID="SqlDataSource3" runat="server"
ConnectionString="<%$ ConnectionStrings:REMConnectionString_development_dev %>"
SelectCommand="LoadUser" SelectCommandType="StoredProcedure"
UpdateCommand="UpdateUser" UpdateCommandType="StoredProcedure"
onupdating="SqlDataSource3_Updating">
<SelectParameters>
<asp:Parameter DefaultValue="c" Name="UserName" Type="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="UserId" Type="String" />
<asp:Parameter Name="DistrictID" Type="Int32" />
<asp:Parameter Name="UserName" Type="String" />
<asp:Parameter Name="MobileAlias" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
the only code in the codebehind is
protected void SqlDataSource3_Updating(object sender, SqlDataSourceCommandEventArgs e)
{
}
It is there so I can drop in a breakpoint and inspect the parameters, which are all there but with null values
Something else has to be at work here. I replicated the code you provided and when I break down the event arguments I see the values and it all works correctly. Could you edit your post and include all the code?
Ok I have had a chance to do some more research and confirmed the issue.
Setting the Master Page ID in the Page_load function is the issue. It needs to be set in the Page_Init.
This page provides a good explanation
http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=469
So by moving
ID= "REM"; from page_load to Page_init the problem magically went away.
Unfortunately it is common to advise setting the ID in Page_Load which is what I relied on and turned out to be bad advice.
DC

Categories

Resources