ddl Selected Value invalid error - asp.net

I have a drop down list inside of a DataList EditItemTemplate, fueled by a SQLDataSource (below). The parameter #panelid is being set in codebehind on the SQL databinding event, and that seems to be working fine. Contents are accurate and what I expected.
Then I tried setting the selected value using Bind("scopeid"), which should be fine. scopeid and equipmentid are related, in fact scopeid is populated by equipmentid in the footer of this same datalist, so their values should be matching (and they are). This should push the scopeid of the chosen record to the selected item in the ddl. However, I get the 'ddlEquipment' has a SelectedValue which is invalid because it does not exist in the list of items. Parameter name: value error when switching to my EditItemTemplate. Any ideas?
<asp:DropDownList class="smallInputddl" ID="ddlEquipment" runat="server" DataSourceID="sqlEditEquipment" SelectedValue='<%# Bind("scopeid")%>' DataTextField="modelnumber" DataValueField="equipmentid" AppendDataBoundItems="true">
</asp:DropDownList>
<asp:SqlDataSource ID="sqlEditEquipment" runat="server" OnDataBinding="sqlEditEquipment_DataBinding" ConnectionString="<%$ ConnectionStrings:ProductionDatabaseConnectionString1 %>"
SelectCommand="select * from tblsls_equipmentscope where proposalnumber in (select proposalnumber from tblsls_cntrlpanel where id = #panelid)">
<SelectParameters>
<asp:Parameter Name="panelid" />
</SelectParameters>
</asp:SqlDataSource>
To demonstrate, here's a Sql query to show the relationship between scopeid and equipmentid. tblsls_cntrlvfd also has the id from tblsls_cntrlpanel.:
select e.equipmentid, c.scopeid from tblsls_equipmentscope e
left join tblsls_cntrlvfd c on e.equipmentid = c.scopeid
where proposalnumber in (select proposalnumber from tblsls_cntrlpanel where id = 20)
Results:
equipmentid scopeid
----------- --------
9513 9513
9541 9541
9543 NULL
(3 row(s) affected)
The gist is that the equipment exists off in it's own little world, and controls in it's. Both get tied to a proposal. There's also a VFD that is associated to both a control panel and a specific piece of equipment.

You'll need to include a 'blank' option in your DDL for it to match the null value to. It's trying to find a match in the list to the cell's original value(null) but since that isn't an available option it's throwing the exception. Just set index 0 of your DDL to be blank.

Figured it out. I'm in the habit of keeping SQL data sources that just fuel a drop down list right with the list they populate. Usually this is desired. In this situation, keeping it with the list resulted in me having to use a work around to set it's parameter's value. It could not see the label it needed to from where it was, so I was setting the default value in the data sources Databinding event. This works fine on it's own, and the list populates as expected. As soon as you try to set the SelectedValue however, when the datasource is having it's parameters setup in databinding, what happens is a slight loading out of order issue. These eventually wind up running at the same time, so the datasource hasn't run and populated it's dataset yet, SelectedValue sees a set with 0 entries in it.
Moving the SQLDataSource out so that it could see the control I originally wanted it to solved the issue. It no longer needed to have it's parameter set through code, it's list is essentially static.

Related

Can't set ASP.NET drop down list to return query value in a datatable

Ok so I have been searching for three days and so far I can not find an answer that explains what I need to do.
Here is what I need. I have an asp.net content page. On that page there are some drop down list boxes. I have a query that fetches data from a SQL DB and puts in a Data table and that is working fine.
What I am trying to do is set the text of the ddl to a string that has been returned from the query.
Here is the HTML side:
<asp:DropDownList ID="ddlProbType" CssClass="ddlEdit" runat="server" Width="150px" DataSourceID="SdsProbType" DataTextField="probtype" DataValueField="probtype" />
Here is the VB code behind:
If dt.Rows.Count > 1 Then
stupidString = dt.Rows(RowCount)("probtype")
ddlProbType.SelectedValue = stupidString
Else
stupidString = dt.Rows(RowCount)("probtype")
ddlProbType.SelectedValue = stupidString
End If
I have added the variable stupidString and the set a break point to check the value being returned and it is correct. When the next line executes the ddl does NOT get the text assigned. I can mouse over the variable stupidString and see that the value it was assigned from the query is correct.
When I have tried setting the ddl directly from the data table, I have tried .ToSting() and .ToString.Trim() to the end of the dt.Rows line but it just will not assign!!
I know this probably something really stupid that I am not doing or overlooking but can anyone help? I do not want to assign a whole sql table to the ddl I just want to set the current list to the value that is returned by the sql query.
You need to populate the list first, e.g. by using
ddlProbType.Items.Add(New ListItem("Key","Value"))
or by using Data Binding.
After the list is populated, then you can tell the control which item should be selected.

Not saving the leading zero from one table to another

An error is thrown on a dropdown list that updates a table field. It claims the SelectedValue is invalid because it does not exist in the list of items. If I go into the table and add the zero to the ID the error is no longer thrown.
The dropdown selects a teacherid which is the primary key from the Teacher table and saves the ID to the Classes table. The classes table saves any IDs that begin with zero without the leading zero.
So if the tid is 0701234 in the Classes table it is saved as 701234 but both tables are nvarchar(255). I might add that the Classes table was using an int datatype for the tid. so I changed it to avoid this. The error above is still thrown after the change, since you cannot update a record that does not exist.
Here is the control
<asp:DropDownList ID="teacherdd1" runat="server" AutoPostBack="true"
DataSourceID="SQLdatasourceTeacherList"
DataTextField="fullname1" DataValueField="tid" >
</asp:DropDownList>
I simply do not know what to do, or why this is happening.
quite simple. i switched to a textbox to test and forgot to double check this. my oversight.
thanks
cmdUpdate.Parameters.Add("#TID1", SqlDbType.Int).Value = teacherdd1.SelectedValue.ToString()
cmdUpdate.Parameters.Add("#TID2", SqlDbType.Int).Value = teacherdd2.SelectedValue.ToString()
'cmdUpdate.Parameters.Add("#tid1", SqlDbType.NVarChar).Value = txbteacher1.Text.ToString()
'cmdUpdate.Parameters.Add("#tid2", SqlDbType.NVarChar).Value = txbteacher2.Text.ToString()
As MRAB already said, you need to follow this data through your code, to make sure it is treated as a string throughout. You mentioned that the field in the classes table used to be an int, which would suggest that int variables may also have been used in the code (for example the parameters to your SQL command?).
So just follow the data, either by stepping through with a debugger, or just following the code. Using the debugger would allow you to check that the data still contains the leading zeroes so that nothing unexpected is happening.
If the above doesn't help, then you will have to provide more of your code in the question, so that someone else might spot what is going on.

ASP.NET GridView OnDataBound Sort in Code Behind

I have a GridView where one of the columns/fields has checkboxes; the checkboxes are checked or unchecked, based on a sub-query from the code behind, while the container GridView is bound to a SqlDataSource. What I want to be able to do is that once the GridView is databound then make it sort by the state of checkboxes: All rows with checkboxes checked appear on the top of grid. Here is part of my GridView:
<ItemTemplate>
<asp:CheckBox ID="ProductSelector" runat="server" Checked='<%# ShowCheckMarks(DataBinder.Eval(Container.DataItem,"prodid").ToString()) %>' />
</ItemTemplate>
I am thinking that I can call the GridView's Ondatabound event and someone make it sort from there?
Thanks.
If that is the only row that you need to sort by why not just add an order by to the sql query you're using to pull the data?
You can save yourself a lot of work if you
store the state of checkbox in database
. That way you can easily set a sort expression on the template field.
Edit
You can do this on clientside via jQuery tablesorter but it might be a
bit too much of work Check this.
Again I think you can somehow manipulate the query to achieve this.
Try this
SELECT dbo.Products.*, dbo.products_recommended.* FROM dbo.Products INNER JOIN dbo.products_recommended ON (dbo.Products.prodid = dbo.products_recommended.prodid) WHERE dbo.Products.prodid IN (dbo.products_recommended.prodid) AND (dbo.Products.prodid = " + itemid + " order by dbo.Products.prodid desc )"
Please note : Never use a
select a.* from YourTable a
This will select all columns from your table & may bring a serious problem later on. Only query the columns you want like
select a.column1,a.column2 from YourTable a
SELECT dbo.Products.prodid,
dbo.Products.itemtitle,
dbo.Products.itemnumber,
dbo.Products.image_1,
CAST(ISNULL(dbo.products_recommended.recommendedid, 0) as BIT) as recommendedid
FROM dbo.Products LEFT OUTER JOIN dbo.products_recommended
ON (dbo.Products.prodid = dbo.products_recommended.prodid)
WHERE dbo.Products.prodid IN (dbo.products_recommended.prodid)
AND (dbo.Products.prodid = #itemid)
The left outer join will make sure it pulls all items from the Products table while only pulling matching items from the products_recommended table. It will also convert the recommendedid to a BIT value which should work with the checkboxes
Like the good helpers here suggested, I needed to have main sql query to populate the GridView to sort the records, instead of a different query in the code behind. So now the Declarative SqlDataSource syntax is the following. This solves the problem.
I learned a few hew things from the feedback here. Thank you all!
SELECT DISTINCT Products.prodid,
Products.itemtitle,
Products.itemnumber,
Products.image_1,
CASE WHEN YESNO IS NULL THEN CAST(0 AS BIT) ELSE CAST(1 AS BIT) END AS CheckUncheck
FROM Products
LEFT OUTER JOIN (SELECT prodid_recommended as YESNO FROM products_recommended
WHERE #itemid IN (prodid) ) A
ON Products.prodid = A.YESNO
ORDER BY CheckUncheck DESC

Columns of two related database tables in one ASP.NET GridView with EntityDataSource

I have two SQL Server tables with Primary Keys (PK) and a Foreign Key (FK) linking the two tables:
1) Table "Order"
OrderID, int, PK
AddressID, int, FK
...
2) Table "Address"
AddressID, int, PK
City, nvarchar(50)
...
Then I've created an (ADO.NET) Entity Data Model out of those two tables.
Now on my (ASP.NET) webpage I put a GridView with an EntityDataSource. In my GridView I want to display two columns:
OrderID
City (belonging to that order and linked by the AddressID-key)
How can I do that? My problem is: When I configure the Entity Data Source I can select an "EntitySetName" which can be
either "Order" or "Address" but not both, nor can I select any kind of relationship. If I select "Order" as EntitySetName
then in the GridView I can add the columns
OrderID
Address
Address.AddressID
Adding the column "Address" displays empty cells. Adding "OrderID" and "Address.AddressID" displays the expected IDs. But how can I
add the "City" of the related address to my GridView?
Thank you for help in advance!
Edit: Clarification:
The Entity Framework has created a class "Order" and a class "Address" corresponding to the database tables. The class "Order" has a reference to an "Address" object as a navigation property, corresponding to the 1-n relationship between Address and Order table.
Basically I want to have a column in my GridView which displays Order.Address.City. I have tried to add a bound field with "Address.City" as data field to the GridView but it results in a runtime error ("no such property...").
OK, much too many hours later I found the solution myself:
Option 1:
It is possible to use the select property in the EntityDataSource which allows to create arbitrary projections of data from several related entities/database tables (in my case: OrderID from Order entity and City from the
Address entity)
Drawback: Using select in the EntityDataSource makes using Insert, Update and Delete in the GridView impossible!
Option 2:
The EntityDataSource must have the include property to include the related address property along with the queried orders. The markup looks likes this:
<asp:EntityDataSource ID="EntityDataSourceOrders" runat="server"
ConnectionString="name=MyEntitiesContext"
DefaultContainerName="MyEntitiesContext"
EntitySetName="Order" Include="Address"
EnableDelete="True" EnableInsert="True"
EnableUpdate="True">
</asp:EntityDataSource>
Then the columns collection of the GridView can have a template field like this:
<asp:TemplateField HeaderText="City" >
<ItemTemplate>
<asp:Label ID="LabelCity" runat="server" Text='<%# Eval("Address.City") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
Here Eval is important. Bind does not work. Also using a BoundField as a column...
<asp:BoundField DataField="Address.City" HeaderText="City" />
... is NOT possible. So it is not possible in the GridView to edit the City (which makes sense because its a related field belonging to another table and perhaps to many other orders). But it is possible to edit flat fields of the order entity and also the "AddressID" of the order to assign another address.

understanding parameters in asp.net databinding

I have a sqldatasource connection in whose parameters, the insert parameter is set as
INSERT INTO [user_info] ([firstname], [lastname], [age]) VALUES (#firstname, #lastname, #age)
Now i understand #firstname, #lastname, #age are the parameters to which i set them the value.
I'm databinding it with a formview, which automatically binds the textbox in the insertitemtemplate with the columns Firstname, lastname and age respectively. For instance the FirstName Text box has the following property.
<asp:TextBox ID="firstnameTextBox" runat="server" Text='<%# Bind("firstname") %>' />
Now my doubt is that, the #firstname variable how is bound with the firstname field. I have not explicitly used the binding anywhere. Say tomorrow i want to rename the insert query as
INSERT INTO [user_info] ([firstname], [lastname], [age]) VALUES (#fn, #ln, #ag)
where and all i will have to make changes inorder to bind #fn with FirstName and so on.
Hope my question is clear.
Short Answer: changing your parameter names won't cause a ripple effect. Changing your column name will.
Detailed Answer: Databinding with Bind (and Eval) in this case applies to the column name of your SQL table, not the parameter name. If you were to start using the 2nd INSERT statement with #fn your Bind would continue to use "firstname" without needing to change.
However, if you updated your table and renamed the "firstname" column to "fn" this is no longer the case and you now have 2 choices:
Update all Bind() calls to use "fn" instead of "firstname" - this would require many changes if it occurs in many places.
Update your SELECT statement (or stored procedure) to alias the fn column as firstname (ie. SELECT [fn] as firstname, ... other columns ... FROM [user_info]) - this is advantageous since the change happens at the source and doesn't affect existing binding to "firstname," which means making a change in only one place.

Resources