"input string format" error binding DetailView to Gridview clicked row - webforms

I'm reacquainting myself with Web Forms programming, using the ubiquitous Northwind database as a backing db for my project. I'm following a simple design pattern for displaying Customers, Products, etc., by displaying a databound gridview at the top of a page, then using the selected row of the gridview to display single item details in a DetailsView. This has been working perfectly well until, for some reason, I started working with a particular table (Suppliers). I am getting the following error:
The display of the Suppliers Gridview itself works perfectly until I add the DetailsView code. My Gridview-related code is as follows:
<asp:GridView ID="gvSuppliers" class="table table-bordered table-condensed table-responsive table-hover" runat="server" AutoGenerateColumns="False"
autogenerateselectbutton="True" AllowPaging="True" DataSourceID="dsSuppliersObjectSource" DataKeyNames="SupplierID" >
<columns>
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" />
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
<asp:BoundField DataField="ContactName" HeaderText="ContactName" SortExpression="ContactName" />
<asp:BoundField DataField="ContactTitle" HeaderText="ContactTitle" SortExpression="ContactTitle" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="Region" HeaderText="Region" SortExpression="Region" />
<asp:BoundField DataField="PostalCode" HeaderText="PostalCode" SortExpression="PostalCode" />
<asp:BoundField DataField="Country" HeaderText="Country" SortExpression="Country" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:BoundField DataField="Fax" HeaderText="Fax" SortExpression="Fax" />
<asp:BoundField DataField="HomePage" HeaderText="HomePage" SortExpression="HomePage" />
</columns>
</asp:GridView>
<asp:ObjectDataSource ID="dsSuppliersObjectSource" runat="server" EnablePaging="True" SelectMethod="GetSuppliers"
SelectCountMethod="GetSuppliersCount" TypeName="Unknown_Web_Forms.SupplierDS" MaximumRowsParameterName="maxRows"
StartRowIndexParameterName="startIndex">
</asp:ObjectDataSource>
Note I am using an object data source; the relevant code, a method named "GetSuppliers", is a simple LINQ query, which, again, is working just fine:
public List<Supplier> GetSuppliers(int startIndex, int maxRows)
{
using (NorthwindEntities entities = new NorthwindEntities())
{
return (from supplier in entities.Suppliers
select supplier)
.OrderBy(supplier => supplier.SupplierID)
.Skip(startIndex)
.Take(maxRows).ToList();
}
}
So far so good. But then I add my DetailsView and try to wire it to my Gridview's selectedValue as the data source:
<asp:DetailsView ID="DetailsView1" runat="server" Height="50px" Width="125px" AutoGenerateRows="False" DataSourceID="SuppliersSingleItemDataSource">
<Fields>
<asp:BoundField DataField="SupplierID" HeaderText="SupplierID" SortExpression="SupplierID" />
<asp:BoundField DataField="CompanyName" HeaderText="CompanyName" SortExpression="CompanyName" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource ID="SuppliersSingleItemDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString2 %>"
SelectCommand="SELECT * FROM [Suppliers] WHERE ([SupplierID] = #SupplierID)">
<SelectParameters>
<asp:ControlParameter ControlID="gvSuppliers" DefaultValue="null" Name="SupplierID" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>
As soon as I do this, I get the error you see in the opening of this question.
What I have tried:
Some Googling of this suggested I try limiting the columns displayed as BoundFields inside the DetailsView; that maybe there was bad data in the table. I have cut down the number of fields to a bare minimum, the SupplierID, which is an integer primary key and therefore can't be null or a non-integer value. I also kept the company name (a string).
Ensured I have an integer DataKeyName (SupplierID) specified in my gridview and it matches the datatype of the DetailViews' datasource (SupplierID, Int32).
The error message is so unhelpful and generic that I'm running out of ideas on how to solve this. Again, I am using this same technique (DetailsView picking up a Select in a Gridview) for other tables and not having this problem. I have painstakingly compared my technique on the pages that work against this one that doesn't work and cannot see a difference. It seems this should be working. Ideas, anyone?

I was able to solve this on my own. The culprit appears to be having a default value of null in the datasource for the the DetailsView. If I leave the default value out (hey,it was in the tutorial I was following!) the DetailsView won't try to display anything until it gets an actual integer from a click on the gridview. Thought I'd leave my question and answer here in case anybody else runs into this situation. Judging by Google, it is a quite common error.
<asp:SqlDataSource ID="SuppliersSingleItemDataSource" runat="server" ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString2 %>"
SelectCommand="SELECT * FROM [Suppliers] WHERE ([SupplierID] = #SupplierID)">
<SelectParameters>
<asp:ControlParameter ControlID="gvSuppliers" Name="SupplierID" PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
</asp:SqlDataSource>

Related

String was not recognized as a valid Boolean. - an Error Related to C#. GridView CheckBoxField

Here is the programming environment.
Framework: ASP.NET Framework 4
Language: Visual C# 2010
Database: Oracle Database 11g
Here is the scenario.
I'm creating a GridView from the HR Sample Schema's HR.EMPLOYEES table. I'm trying to convert the incoming data from the COMMISSION_PCT column into a boolean value and populate the GridView with check boxes under the DataField for COMMISSION_PCT, so the employees with a value in this field will be shown with the checked check box. This is how the GridView object control looks so far.
<asp:GridView ID="GridViewEmployees" runat="server" AllowSorting="True" CellPadding="4"
DataSourceID="SqlDataSourceOracle" GridLines="None" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="EMPLOYEE_ID" HeaderText="Employee ID" SortExpression="EMPLOYEE_ID" />
<asp:BoundField DataField="FIRST_NAME" HeaderText="First Name" SortExpression="FIRST_NAME" />
<asp:BoundField DataField="LAST_NAME" HeaderText="Last Name" SortExpression="LAST_NAME" />
<asp:BoundField DataField="EMAIL" HeaderText="E-mail Address" SortExpression="EMAIL" />
<asp:BoundField DataField="PHONE_NUMBER" HeaderText="Phone Number" SortExpression="PHONE_NUMBER" />
<asp:BoundField DataField="HIRE_DATE" HeaderText="Hire Date" SortExpression="HIRE_DATE" />
<asp:BoundField DataField="JOB_ID" HeaderText="Job ID" SortExpression="JOB_ID" />
<asp:BoundField DataField="SALARY" HeaderText="Salary" SortExpression="SALARY" />
<asp:CheckBoxField DataField="COMMISSION_PCT" HeaderText="Receives Commission" SortExpression="COMMISSION_PCT" />
<asp:BoundField DataField="MANAGER_ID" HeaderText="Manager ID" SortExpression="MANAGER_ID" />
<asp:BoundField DataField="DEPARTMENT_ID" HeaderText="Department ID" SortExpression="DEPARTMENT_ID" />
</Columns>
</asp:GridView>
Of course, when I try to preview the page as it is, I'll get the following error message:
Server Error in '/' Application.
String was not recognized as a valid Boolean.
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.FormatException: String was not recognized as a valid Boolean.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[FormatException: String was not recognized as a valid Boolean.]
...
[HttpException (0x80004005): The data in the CheckBoxField 'COMMISSION_PCT' could not be parsed as a boolean value. Try using a BoundField instead.]
...
So far, I thought about using DECODE for the SQL statement, but that would still return a string value. Unfortunately, with the C# encompassing strong typing programming discipline and Oracle not supporting the boolean data type in SQL statements, it seems that I'll need to make this transition with the code behind. Got any suggestions on how to make this happen?
Behind the scenes, I'd guess Boolean.Parse is being called which expects a string like "false". If that's the case decode or a case statement should work:
select decode(commission_pct,0,"false", "true") as has_commission
from your_table
This example worked for me:
<form id="form1" runat="server">
<div>
<asp:GridView ID="PnlData" runat="server" DataSourceID="SqlDataSource1">
<Columns>
<asp:CheckBoxField DataField="Bln" HeaderText="Bln Test" SortExpression="Bln" />
</Columns>
</asp:GridView>
</div>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
ProviderName="<%$ ConnectionStrings:ConnectionString.ProviderName %>" SelectCommand="select 'true' as bln from dual union select 'false' as bln from dual union select 'True' as bln from dual">
</asp:SqlDataSource>
</form>

AJAX Tab Panel and Binding DataTable

I am trying to find a way to bind a data table to a tab panel (within a tabcontainer and template) without doing it on page_init or page_load. OR Binding a data table to a gridview then binding that gridview to the tab panel. I know how to bind a data table to a gridview so that's the easy part. I have to be able to - on click of a button - add or create multiple tabs in that tab container.
I want the user to be able to click a button, run some queries and then make the tab container visible and bind the data from a data table to a panel at that time (then the panel to the tab container). Do this multiple times.
Can someone provide an example or explain how I can accomplsih this? Is Update Panel my answer and where can I find some good examples?
UPDATE
I found that it was very easy to bind data to a gridview within Ajax tabs. Of course you needed you script manager ajax reference declared in the asp page and web.config file. You also need to add the ajax css style to an existing style sheet. i tried using a seperate one and it didn't work.
ASP HTML
<AjaxToolkit:TabContainer ID="TabContainer1" runat="server" ActiveTabIndex="0"
Visible="false" ScrollBars="Both"
CssClass="Tab2" Width="1326px" Height="464px" >
<AjaxToolkit:TabPanel ID="TabPanel1" runat="server" HeaderText="Empty" Enabled="true" ScrollBars="Both" CssClass="Tab2">
<ContentTemplate>
<div style="overflow:auto;width:1287px; height: 418px;">
<font color="white" size="1" face="Verdana">
<asp:GridView ID="SalesOrderView1" runat="server" BackColor="White" BorderColor="#DEDFDE"visible="False"BorderStyle="None" BorderWidth="1px"
CellPadding="4" ForeColor="Black"
GridLines="Vertical" HorizontalAlign="Center">
<AlternatingRowStyle BackColor="White" />
<FooterStyle BackColor="#CCCC99" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#F7F7DE" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#FBFBF2" />
<SortedAscendingHeaderStyle BackColor="#848384" />
<SortedDescendingCellStyle BackColor="#EAEAD3" />
<SortedDescendingHeaderStyle BackColor="#575357" />
</asp:GridView>
</div>
</font>
</ContentTemplate>
</AjaxToolkit:TabPanel>
<AjaxToolkit:TabPanel ID="TabPanel2" runat="server" HeaderText="Empty" ScrollBars="Both" CssClass="Tab2">
<ContentTemplate >
</AjaxToolkit:TabContainer>
C# Code to bind data to the gridview on click button event.
SalesOrderView1.Visible = true;
TabPanel1.Visible = true;
TabPanel1.HeaderText = Order_List[multi_order_count];

How do I sort a DataGrid column based on a field in an embedded Repeater?

I have a DataGrid which has one column that derives its contents from a Repeater that is populated during the DataGrid's ItemDataBound event. I need to be able to sort the DataGrid rows based on the value in the Repeater. Here is a shortened sample of the DataGrid:
<DataGrid id="dgResults" Runat="server" AllowSorting="true">
<Columns>
<asp:boundcolumn HeaderText="ID" datafield="group_id" Visible="False" />
<asp:BoundColumn HeaderText="Group" DataField="group_name" SortExpression="group_name" />
<asp:TemplateColumn SortExpression="meeting_start_time">
<HeaderTemplate>
<asp:LinkButton CommandName="Sort" Text="Time" CausesValidation="False" runat="server" />
</HeaderTemplate>
<ItemTemplate>
<asp:Repeater ID="Schedule_Repeater" runat="server">
<ItemTemplate>
<%# Eval("meeting_start_time", "{0:t}")%>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
</DataGrid>
As you can see, the third column contains the meeting_start_time, whose value is displayed via a Repeater.
How do I tell the DataGrid to sort the "Time" column by the meeting_start_time values in the Repeater?

GridView sorting with Template Field and Header Template

I'm using GridView and there is a dropdownlist in header cell for filtering.
<gm:GridView ID="routePlanGridView" runat="server" AutoGenerateColumns="False"
AllowPaging="true" PageSize="20" GridLines="Both" ShowFooter="true" CssClass="grid"
DataKeyNames="RoutePlanId" OnSorting="routePlanGridView_Sorting"
AllowSorting="true" OnPageIndexChanging="routePlanGridView_PageIndexChanging"
OnSelectedIndexChanging="routePlanGridView_SelectedIndexChanging"
OnRowDataBound="routePlanGridView_RowDataBound"
OnRowEditing="routePlanGridView_RowEditing"
OnRowUpdating="routePlanGridView_RowUpdating">
<HeaderStyle CssClass="gridHeaderFooter" />
<FooterStyle CssClass="gridHeaderFooter" />
<RowStyle CssClass="gridRow" />
<AlternatingRowStyle CssClass="gridRowAlternate" />
<Columns>
<asp:TemplateField SortExpression="SPName">
<HeaderTemplate>
SP Name<br />
<asp:DropDownList ID="spNameFilterDDL" runat="server" CssClass="gridControl" AutoPostBack="true" DataSourceID="SPNameSDS" DataTextField="SPName" OnDataBound="filterDDL_DataBound" OnSelectedIndexChanged="spNameFilterDDL_SelectedIndexChanged" />
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="spNameLabel" runat="server" Text='<%# Bind("SPName") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<...15 more...>
</Columns>
</gm:GridView>
and there are relevant event handlers for sorting and paging.
Now the problem is if I put "SP Name" text in a link button, page crashes when link clicked, otherwise no link produced to sort.
If I remove Header Template fields (all of them) and put a text with HeaderText attribute of TemplateField it works as expected. Is there a way to put them together? I need that dropdown and also sorting.
Thanks.
sorry, forgot to insert the code correctly - here:
<asp:LinkButton runat="server" Text="SP Name" CommandName="Sort" CommandArgument="SPName" ></asp:LinkButton>
You need to use a link button for your header text. So in place of "SP Name", use . It should work if you are handling sorting.

Binding navigation property to RadGrid while using EntityDataSource control

I'm new to Entity Framework and I got stuck in an issue while trying to bind a navigation property (foreign key reference) to a dropdownlist. I have Telerik RadGrid control which gets the data using a EntityDataSource control. Here is the model description:
Applications: AppId, AppName, ServerId
Servers: ServerId, ServerName
The Applicaitons.ServerId is a foreign key reference to Servers.ServerId. The RadGrid lists the applications and allows the user to insert/update/delete an application. I want to show the server names as a dropdownlist in edit mode which I'm not able to. . Here is my aspx code:
<telerik:RadGrid ID="gridApplications" runat="server" Skin="Sunset"
AllowAutomaticInserts="True" AllowAutomaticDeletes="True"
AllowPaging="True" AllowAutomaticUpdates="True"
AutoGenerateColumns="False" OnItemCreated="gridApplications_ItemCreated"
DataSourceID="applicationsEntityDataSource" Width="50%"
OnItemInserted="gridApplications_ItemInserted"
OnItemUpdated="gridApplications_ItemUpdated"
OnItemDeleted="gridApplications_ItemDeleted" GridLines="None">
<MasterTableView CommandItemDisplay="Top" AutoGenerateColumns="False" DataKeyNames="AppId" DataSourceID="applicationsEntityDataSource">
<RowIndicatorColumn>
<HeaderStyle Width="20px" />
</RowIndicatorColumn>
<ExpandCollapseColumn>
<HeaderStyle Width="20px" />
</ExpandCollapseColumn>
<Columns>
<telerik:GridEditCommandColumn ButtonType="ImageButton" UniqueName="EditCommandColumn" HeaderText="Edit" ItemStyle-Width="10%">
</telerik:GridEditCommandColumn>
<telerik:GridButtonColumn CommandName="Delete" Text="Delete" UniqueName="DeleteColumn" ConfirmText="Are you sure you want to delete this application?" ConfirmTitle="Confirm Delete" ConfirmDialogType="Classic" ItemStyle-Width="10%" HeaderText="Delete">
</telerik:GridButtonColumn>
<telerik:GridBoundColumn DataField="AppId" UniqueName="AppId" Visible="false" HeaderText="Application Id" ReadOnly="true">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="AppName" UniqueName="AppName" HeaderText="Application Name" MaxLength="30" ItemStyle-Width="40%">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn DataField="ServerId" UniqueName="ServerId" HeaderText="Server Hosted" EditFormColumnIndex="1">
<EditItemTemplate>
<asp:DropDownList ID="ddlServerHosted" runat="server" DataTextField="Servers.ServerName" DataValueField="ServerId" Width="40%">
</asp:DropDownList>
</EditItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
<EditFormSettings ColumnNumber="2" CaptionDataField="AppId" InsertCaption="Insert New Application" EditFormType="AutoGenerated">
<EditColumn InsertText="Insert record" EditText="Edit application id #:" EditFormColumnIndex="0" UpdateText="Application updated" UniqueName="InsertCommandColumn1" CancelText="Cancel insert" ButtonType="ImageButton"></EditColumn>
<FormTableItemStyle Wrap="false" />
<FormTableStyle GridLines="Horizontal" CellPadding="2" CellSpacing="0" Height="110px" Width="110px" />
<FormTableAlternatingItemStyle Wrap="false" />
<FormStyle Width="100%" BackColor="#EEF2EA" />
<FormTableButtonRowStyle HorizontalAlign="Right" />
</EditFormSettings>
</MasterTableView>
</telerik:RadGrid>
<asp:EntityDataSource ID="applicationsEntityDataSource" runat="server"
ConnectionString="name=AnalyticsEntities" EnableDelete="True"
EntityTypeFilter="Applications" EnableInsert="True" EnableUpdate="True" EntitySetName="Applications"
DefaultContainerName="AnalyticsEntities" Include="Servers">
</asp:EntityDataSource>
I tried another approach where I replaced the GridTemplateColumn with the following code
<telerik:RadComboBox ID="RadComboBox1" DataSourceID="serversEntityDataSource" DataTextField="ServerName" DataValueField="ServerId" AppendDataBoundItems="true" runat="server" >
<Items>
<telerik:RadComboBoxItem />
</Items>
and using a separate EntityDataSource control as follows:
<asp:EntityDataSource ID="serversEntityDataSource" runat="server"
ConnectionString="name=AnalyticsEntities" EnableDelete="True"
EntityTypeFilter="Servers" EnableInsert="True" EnableUpdate="True" EntitySetName="Servers"
DefaultContainerName="AnalyticsEntities">
</asp:EntityDataSource>
but, I get the following error.
Application cannot be inserted. Reason: Entities in 'AnalyticsEntities.Applications' participate in the 'FK_Servers_Applications' relationship. 0 related 'Servers' were found. 1 'Servers' is expected.
My question is, how do you bind the navigation property and load the values in the DropDownList/RadComboBox control?
I believe you bind your dropdownlist to that second datasource instead of the grid's datasource (as you did in the second example). Then you set the SelectedValue property on the dropdown/combobox using the <%# BIND("ServerId") %> syntax within the template.

Resources