Gridview's UPDATE does not like the space in my parameter - asp.net

Unfortunately, the database I'm dealing with has a space in the column name. I have a DropDownList in a GridView and I'm trying to update the column with whatever the user selects in the DropDownList. Here's how I have the DropDownList:
<asp:TemplateField HeaderText="Phase (edit)" SortExpression="EditedPhase">
<EditItemTemplate>
<asp:DropDownList ID="PhaseDropDownList" runat="server" DataSourceID="PhaseDropDown" DataTextField="Current Project Phase" DataValueField="Current Project Phase" SelectedValue='<%# Bind("Phase") %>'>
</asp:DropDownList>
</EditItemTemplate>
<asp:TemplateField>
Here's the data source:
<asp:SqlDataSource ID="PhaseDropDown" runat="server" ConnectionString="<%$ ConnectionStrings:ODSConnectionString %>" SelectCommand="select distinct [Current Project Phase] from [Phase_Table]">
</asp:SqlDataSource>
Here's how I have my update command and the parameter:
UpdateCommand="UPDATE [Pipeline] SET EditedPhase = #[Current Project Phase]"
<UpdateParameters>
<asp:Parameter Name="[Current Project Phase]" Type="String"/>
</UpdateParameters>
After doing a little bit of research, I discovered that you can not have spaces in the parameter, but most of the solutions used the code behind. I have no code behind because introducing code behind could potentially break it (needing to deal with page loads and such). How do I fix my current issue?
If there's a typo, sorry.

Yes, do not use spaces in your parameter name; the value passed to the parameter can have spaces though, so I'm not sure if that is a point of confusion. For instance, update your SQL query like:
UpdateCommand="UPDATE [Pipeline] SET EditedPhase = #CurrentProjectPhase">
<UpdateParameters>
<asp:Parameter Name="CurrentProjectPhase" Type="String" DefaultValue="Current Project Phase"/>
</UpdateParameters>
Here the value (the DefaultValue is a default to supply to the update when no value is provided) can have spaces just fine. But the name cannot. You can set the DefaultValue of the parameter in code or use a more capable parameter (like session, control parameters) to grab values from something...

Related

SqlDataSource with DropDownList Control Parameter doesn't read value

I have a drop down list that bound to a SqlDataSource.
I have another drop down list that's bound to a different SqlDataSource.
The second SqlDataSource has the first drop down as a Control Parameter.
I'm trying to do this...
<asp:SqlDataSource ID="sqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT * FROM Test WHERE Param = #param;"
CancelSelectOnNullParameter="true">
<SelectParameters>
<asp:ControlParameter ControlID="dropDown1" Name="param"
PropertyName="SelectedValue"
ConvertEmptyStringToNull="true" />
</SelectParameters>
</asp:SqlDataSource>
dropDown1.SelectedValue = "someValue"
dropDown2.DataBind()
but I don't get any results. However, if I set the second SqlDataSource's Control Parameter to a text box, it works. For example, this works:
<asp:ControlParameter ControlID="txt" Name="param"
PropertyName="Text"
ConvertEmptyStringToNull="true" />
txt.Text = "someValue"
dropDown2.DataBind()
Any ideas why this is?
I ended up figuring this one out. The problem was that the drop down was attempting to bind twice, much like the problem in this question.
I used the suggestion made by Joel Etherton, and now it works perfectly. Although I used a hidden control rather than a label.

asp:sqldatasource SelectCommandType="Text" Dropdown not populating ONLY when parameters are passed to SQL

I'm trying to use a asp:SqlDataSource driven by a SQL Select with Arguments. It works as long as I don't have any arguments. I can run the parameterized query via studio and it works and returns rows. If I any arguments, then the asp:View doesn't render.
First, the code returns 2 rows when I execute the SQL via Studio.
Second, I don't want it as a stored proc. Deployment issue. Smile, let it go. :-)
<asp:DropDownList ID="lstUsers" runat="server" DataSourceID="sqlGetCSGUsersOnClaim" DataTextField="username" DataValueField="userID" />
<asp:SqlDataSource ID="sqlGetCSGUsersOnClaim" runat="server" ConnectionString="<%$ ConnectionStrings:SiteSqlServer%>" SelectCommandType="Text" SelectCommand="
SELECT aspnet_Users.UserId as userID, aspnet_users.username as username
FROM claims, aspnet_Users
WHERE claims.claimid = #ClaimID and
(Claims.AdjusterID = aspnet_Users.UserId or Claims.SupervisorID = aspnet_Users.UserId )">
<SelectParameters>
<asp:SessionParameter Name="ClaimID" SessionField="ClaimID" Type="Int32" DbType="Int32" />
</SelectParameters>
</asp:SqlDataSource>
If I remove the #ClaimID and SelectParameters arguments, the dropdown populates. It only fails once I add the parameter.
What am I doing wrong?
Thanks in advance,
Jason
Well it turned that if I removed the Type and DBType attributes of the SelectParameter, the code worked. sigh....
I have no idea, why though.

change text on a hyperlink in a datalist

I'm trying to bind a column from a SQL code that i have written to all hyperlinks in a datalist. This should be really simple but I'm getting the error
DataBinding: 'System.Data.Common.DataRecordInternal' does not contain
a property with the name 'NumberOfComments'.
Well I'm pretty sure the column exist but in this case it's created by a function maybe that has something to do with it. When I run the SQL code i get the values I should.
The hyperlink
<asp:HyperLink ID="lnkComment" runat="server"
NavigateUrl='<%# Eval("ID", "~/Default.aspx?ID={0}") %>'
Text='<%# Eval("NumberOfComments") %>'></asp:HyperLink>
The SQLDataSource
<asp:SqlDataSource ID="sdsNews" runat="server"
ConnectionString="<%$ ConnectionStrings:ASPNETDBConnectionString %>" SelectCommand="SELECT News.ID, News.Topic, News.Text, News.PostTime, aspnet_Users.UserName, "NumberOfComments" = dbo.fnNumberOfCommentOnNews(News.ID)
FROM News INNER JOIN
aspnet_Users ON News.UserId = aspnet_Users.UserId
WHERE (News.ID = ISNULL(#ID, News.ID))
ORDER BY News.PostTime DESC ">
<SelectParameters>
<asp:QueryStringParameter DbType="Guid" Name="ID" QueryStringField="ID" DefaultValue="" />
</SelectParameters>
</asp:SqlDataSource>
Why do you have """ surrounding NumberOfComments FieldName?
Try pasting the select command into SSMS (SQL Server Mgmt studio) and you should most definitely get an incorrect syntax error. If you drop those quot html code you will still be able to reference and bind to that column.

How do you have multiple controls for a gridview?

For example, I have a gridview and two textboxes.
One textbox is for the text to search for.
The second textbox is an order number to search for.
I want my gridview to populate based on one or the other. I don't know how to tell my form if the user is using a number search by that and if a name, instead search by that.
Thanks for any help.
OK hope you haven't solved this yet because I took a few minutes to come up with an example that I think will do pretty much what you want.
DB access uses a stored procedure but you can use a ObjectDataSource with DAL, or just inline the SQL statement on the SqlDataSource, etc.
Markup:
Product ID:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
<asp:CompareValidator ID="CompareValidator1" ControlToValidate="TextBox1" runat="server" ErrorMessage="You must enter a number"
ValidationGroup="vg1" Type="Integer" Operator="DataTypeCheck"></asp:CompareValidator>
<br />
Description:
<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox><br />
<asp:Button ID="cmdSearch" runat="server" Text="Search" ValidationGroup="vg1" /><br />
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSource1">
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" SelectCommand="spGetProducts"
CancelSelectOnNullParameter="False" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:ControlParameter ControlID="TextBox1" PropertyName="Text" DbType="String" DefaultValue="" />
<asp:ControlParameter ControlID="TextBox2" PropertyName="Text" DbType="Int32" DefaultValue="" />
</SelectParameters>
</asp:SqlDataSource>
And T-SQL for your query:
CREATE PROCEDURE spGetProducts
#ProductId int = NULL
,#ProductDescription nvarchar(100) = NULL
AS
BEGIN
SELECT [ProductId]
,[ProductDescription]
FROM [Products]
WHERE (
(
(#ProductId IS NULL)
OR
([ProductId] LIKE % + #ProductId + %)
)
AND
(
(#ProductDescription IS NULL)
OR
([ProductDescription] LIKE % + #ProductDescription + %;)
)
);
END
If the user doesn't enter anything in either of the fields, the SqlDataSource will still bind due to SqlDataSource.CancelSelectOnNullParameter = False but the empty parameter will not be sent with the query due to ControlParameter.DefaultValue being set. The stored procedure will then insert the NULL value into the parameter and basically skip that part of the filtering in the WHERE clause.
Hope this helps.
You can check the textboxes by using (TextBox1.Text.Trim.Length > 0) or (TextBox1.Text = "")
It sounds like what you are really asking is how do you filter your data source based on more than one possible filter parameter. Explaining that would require knowing what your data source is. Either way, the gridview is just going to display the filtered results, right?
If you are using SQL for your data source the technique is going to be totally different than filtering a collection in memory. So more information on that would be helpful.

EntityDataSource Null Update Pameters not getting marked Modified

I am using an EntityDataSource with a FormView on VB.NET application. The FormView contains an AjaxControlToolKit TabContains with multiple tabs. Due to the fact that each tab is a naming container, Bind doesn't work properly for updating values (as discovered from reading other posts on stackoverflow). I instead have to declare UpdateParameters on my EntityDataSource. Example markup is as follows:
<asp:FormView ID="fv" runat="server" DataSourceID="eds" DataKeyNames="ID">
<EditItemTemplate>
<asp:TabContainer ID="tc" runat="server">
<asp:TabPanel ID="tp" runat="server" HeaderText="Tab 1">
<ContentTemplate>
<asp:TextBox ID="tbName" runat="server" Text='<%#Eval("Name") %>'></asp:TextBox>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
</EditItemTemplate>
</asp:FormView>
<asp:EntityDataSource ID="eds" runat="server" ConnectionString="name=NDSEntities"
DefaultContainerName="NDSEntities" EnableFlattening="False" EntitySetName="Customers"
Where="it.ID = #ID" EnableUpdate="true" EnableInsert="true">
<WhereParameters>
<asp:QueryStringParameter Name="ID" QueryStringField="ID" DbType="Guid" />
</WhereParameters>
<UpdateParameters>
<asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</UpdateParameters>
<InsertParameters>
<asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</InsertParameters>
</EntityDataSource>
This works great, until a customer is edited and their name is set to nothing (assuming in this case, a null name is allowed). The Name UpdateParameter is set to Null but the ObjectStateEntry is not set to modified for Null properties, even if previously the Entity had a value specified. As long as the name is changed to something other than Null, everything is updated correctly.
I found a workaround by putting the following code in the Updating event of the EntityDataSource.
Dim ose As ObjectStateEntry = context.ObjectStateManager.GetObjectStateEntry(action)
For Each p As Parameter In eds.UpdateParameters
ose.SetModifiedProperty(p.Name)
Next
This makes sure that each property in the UpdateParameters has its state set to modified. It works, but it seems like a hack and I can see it causing problems down the road. Is there anything else I could do?
Do you have an "Concurrency Mode" set for the entity in question? Depending on how you actually update the entity (I haven't used the EntityDataSource, but I'm guessing it internally uses the ObjectContext.Attach method), the code that creates the SQL statement, will try to update only those columns that are actually changed.
Consider the following:
void UpdatePersonEntity(int id, string firstName, string lastName)
{
Person p = new Person { Id = id };
this.Context.People.Attach(p);
p.FirstName = firstName;
p.LastName = lastName;
this.Context.SaveChanges();
}
If firstName or lastName is null, the ObjectContext would assume that it's original value hasn't been touched. This might be something you should look into. I apologize if this isn't helpful, but it might push you in the right direction.

Resources