I am using databinding to iterate through a recordset returned from the database, and one of those recordsets is a comma separated list of items - I'm trying to use a second repeater to display each of those items as a hyperlink. So far this is the code that I have:
<asp:Repeater ID="myRepeater" runat="server" DataSource='<%# DataBinder.Eval(Container.DataItem, "SomeList").ToString().Trim(',') %>'>
<ItemTemplate>
<a href='http://somesite/downloadattachment.aspx?itemid=<%# Container.ItemIndex %>'><%# Container.DataItem %></a>
</ItemTemplate>
</asp:Repeater>
The trouble is that so far there are 3 reasons why this doesnt work:
I get a server tag is not well formed error unless I remove the runat="server" - why is this? (And why does it work without the runat="server"?)
Container.DataItem Evaluates to an instance of System.Data.DataRowView - how do I get the current piece of the string that I split?
More importantly, this only seems to print out 1 Container.DataItem, even when I know there is a comma in the string I've given it - any ideas?
Instead of Eval(), for non-trivial scenarios I generally cast Container.DataItem to the type I want, and then act on it from there in a type-safe way.
The "not well formed" error is caused by the single-quotes around the parameter to Trim(). If you use single quotes on the outside of your attribute definition, you can't use them inside it. In cases like yours where a databinding definition has a lot of code in it, I often create a helper method (either inside a script runat=server for for MVC views and other inline-code-friendly cases, or in code-behind for traditional web forms apps) which handles the code I want to run. By refactoring into a method, it clarifies the HTML and sidesteps the lame single/double-quote restrictions.
Regardless of where you put the code, In your case, you want to:
cast Container.DataItem to DataRowView
extract the SomeList column value using the [] operator
call String.Split() on that string to turn your CSV string it into an array of strings
use that as a data source of your inner repeater
The code should look something like this:
<asp:Repeater ID="myRepeater" runat="server"
DataSource='<%# ((System.Data.DataRowView)Container.DataItem)["SomeList"].ToString().Split(new string[] {","}, StringSplitOptions.RemoveEmptyEntries)%>'>
<ItemTemplate>
<a href='http://somesite/downloadattachment.aspx?itemid=<%# Container.ItemIndex %>'>
<%# Container.DataItem %>
</a>
</ItemTemplate>
</asp:Repeater>
Did you specify the updatecommand, deletecommand to the sqldatasource?
Even if the proper parameters haven't been supplied, the affected rows will always be 0. If it has two parameters for the update command, two parameters have to be supplied through updatecommand.
For more information on this please check this URL: http://www.itpian.com/Coding/4774-Data-binding.aspx
Related
I am trying to assign an Eval value to a variable and trying to use that inside a repeater. Here's a brief example of what I am trying to do:
<ItemTemplate>
<% var test= Eval("year") %>
<asp:Repeater DataSource='testlist'>
<ItemTemplate>
<a class="testclass" href='/testlink/<%= test%>/'>Test this</a>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
I end up getting this error
CS0103: The name 'test' does not exist in the current context
I think my syntax is wrong. I tried looking for options for this online but most of them suggested a variable in the code behind. I am working with Sitefinity Webform templates, so would like to avoid code behind. Is there any way to do something on the aspx page itself instead of a code behind?
One thing I forgot to mention is that the testlist does not have year property. The year property exists outside the repeater. And hence I want to assign it to a variable and use.
Use like below
<ItemTemplate>
<asp:Repeater DataSource='testlist'>
<a href='/testlink/<%#DataBinder.Eval(Container.DataItem, "test") %>'>Test this</a>
</asp:Repeater>
</ItemTemplate>
My code is like this
<asp:Repeater ID="rptEvaluationInfo" runat="server">
<ItemTemplate>
<asp:Label runat="server" Id="lblCampCode" Text="<%#Eval("CampCode") %>"></asp:Label>
</ItemTemplate>
Everything looks okay to me, But it generates an error in the runtime. When I remove this part
Text="<%#Eval("CampCode") %>"
error goes.
SO I assume the issue is with databind. So I tried an alternative like this
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<label><%#Eval("CampCode") %> </label>
</ItemTemplate>
And it also works good. Can any one tell me what is the issue with my first code?
Note: I don't have access to the error message due to the special
reasons on my project , that's why I have not posted it here.
And I want to use ASP controls itself on the case that's why i haven't
gone with my second solution
The problem is with quotes. Currently you have double quotes everywhere, so ASP.NET is not able to parse this. Change outer ones to single quotes like this:
Text='<%#Eval("CampCode") %>'
Why
<a id="link" runat="server" href="javascript:downloadFile('<%#Eval("TempKey") %>')"><%#Eval("ShortFileName") %></a>
is giving me The server tag is not well formed exception in my asp.net application?
What' is wrong ? If I remove runat="server", then it is OK . But I need to handle it (which is inside a gridview) from the code behind .
Thanks a lot !!
In my grid view i have used Linkbutton and applied following code on OnClientClick.
<asp:TemplateField HeaderText="Print">
<ItemTemplate>
<asp:LinkButton ID="lbtn_prntmenu" runat="server" CssClass="mlinks" CommandArgument='<%#Eval("ID")%>' CommandName="Print" Text="Print" OnClientClick='<%#Eval("ID","javascript:downloadFile(\"{0}\");")%>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Similarly you can do with you <a> element on href
You get The server tag is not well formed error because you are using double quotes within double quotes making attribute-name="value" kind of syntax going hay-wire. It would be parsed by ASP.NET compiler as something like
href="javascript:downloadFile('<%#Eval(" TempKey ") %>')">
TempKey would appear as separate attribute with no value etc.
When you remove server tags, ASP.NET would not parse the html element syntax it but rather emit it as it is (its invalid html as well as but browsers are far more forgiving).
You should probably try it within single quotes such as
href='javascript:downloadFile("<%#Eval("TempKey") %>")'
EDIT
Above would still produce problematic html as there would be un-escaped double quote in href value. So try this:
href='javascript:downloadFile("<%#Eval("TempKey") %>")'
EDIT
It appears that data binding expression is not getting evaluated in above. Please try below expression which uses Eval overload for formatting
href='<%# Eval("TempKey", "javascript:downloadFile("{0}")") %>'
EDIT
Yet another alternative is to use some code-behind method - for example,
href='<%# GetFileLink(Container.DataItem) %>)'
And in code-behind
protected string GetFileLink(object dataItem)
{
return string.Format("javascript:downloadFile('{0}');",
DataBinder.Eval(dataItem, "TempKey"));
}
What' is wrong ?
The ASP.NET parser messes with the nested double quotes.
I just realize it does not seem to happen with VS2012 anymore.
If I remove runat="server", then it is OK . But I need to handle it (which is inside a gridview) from the code behind .
If you have a class for your DataItem, you could just try casting :
<a id="link" runat="server" href="javascript:downloadFile('<%#((YourNamespace.YourClass)Container.DataItem).TempKey%>')"><%#Eval("ShortFileName") %></a>
Best thing to do should be to set the href in codebehind (this is a point of having a runat="server" control)
Hope this will help,
Try following code:
onclick='<%# "return jsPopup('UpdateProbAct.aspx?Table=problems&Deptid=" + Eval("department") %>'
I have discovered that it is possible to populate resource strings with variable information using string.format, see below:
String.Format(Resources.Temp.TempString, Resources.Contact.PhoneSales)
I can display this on my page using:
<p><%= String.Format(Resources.Temp.TempString, Resources.Contact.PhoneSales) %></p>
In some cases I have a Label or Literal (or any control) which might dynamically hide or show content. Ordinarily I would populate those using:
<asp:Literal ID="Literal1" Text="<%$ Resources:Temp,ContactUs %>" runat="server" />
I now would like the same String.Format functionality whilst still using controls. I found Display value of Resource without Label or Literal control but this doesn't actually work for me, it just writes out '<%= GetGlobalResourceObject("Messages", "ThankYouLabel") %>' on the page (not the content, that actual string).
UPDATE:
I have found a solution which works with some controls:
<asp:Label runat="server" ID="temp"><%= String.Format(Resources.Temp.TempString, Resources.Contact.PhoneSales) %></asp:Label>
However, this works doesn't work for Literal controls as they don't allow child controls. I'd prefer to keep using Literal's as they are the cleanest in terms of code generated, so still seeking a solution.
asp:Literal doesn't support <%= %> construct, and doesn't allow child controls (I mean something like <asp:Literal runat="server"><%= ... %></asp:Literal>).
But if you use data binding, your could use data-binding expresions <%# ... %>:
<asp:Label runat="server" Text="<%# string.Format(...) %>"></asp:Label>
To make this work you should ensure that either implicit or explicit data binding for your controls is used. Otherwise the control like this without binding outputs nothing.
This workaround is a little bit complex. Consider using either asp:Label control, or set the Text property from the code behind.
To solve my problem I have actually had a second look at how I am displaying content and found that a lot of times the Literals and Labels could be dropped in place of plain HTML code. I can then use my preferred method <%= ... %> to display content.
You could use an asp:PlaceHolder control instead of a Literal.
PlaceHolders can contain child controls; they also support <%= … %>-style "displaying expressions".
<% if(Eval("SaveDate") != DBNull.Value){ %>
do magic
<%} %>
gives me error: Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
I could write : <%# Eval("SaveDate") != DBNull.Value ? do magic
But I need to do lots of html magic in if statement.
I know I should add # in order to use Eval, but not sure about correct syntax.
One solution is to wrap the content in a runat="server" tag with a Visible value, e.g.,
<div runat="server" Visible='<%# Eval("SaveDate") != DBNull.Value %>'>
do magic
</div>
div can be any HTML tag, but <asp:Panel> and <asp:PlaceHolder> could also be used. Note that "do magic" is still databound, so it's not a perfect solution if it contains expensive code or code that could generate an error if Eval("SaveDate") == DBNull.Value.
Note that Visible="false" will omit the tag and all its contents from the generated HTML, this means that it is very different from style="display:none" or style="visible:hidden", so don't worry about that.
But, if your "do magic" is reasonably complex, another rather simple solution (a bit of a hack) is: use a Repeater (or FormView) with its DataSource set to an array of one item (visible) or no items (hidden):
<asp:Repeater runat="server" DataSource='<%# ElementIfTrue(Eval("SaveDate") != DBNull.Value) %>'
<ItemTemplate>
do magic
</ItemTemplate>
</asp:Repeater>
protected IEnumerable ElementIfTrue(bool condition)
{
if (condition)
return new object[] { Page.GetDataItem() };
else
return new object[0];
}
The actual contents of the datasource array is either empty (hidden) or the element you were already binding to. This makes sure you can still call <%# Eval(...) %> inside the ItemTemplate.
With this approach, your "do magic" is a template which will only be executed if DataSource has one or more items. Which is taken care of by ElementIfTrue. It's a bit of a mind bender, but it can save you every once in a while.
As a side note: packing your "do magic" in a user control can also keep the complexity down. You don't really need to change a thing in your HTML/ASP.NET tag mix (<%# Eval("...") %> still works even inside a user control).
I usually add a protected function returning a string to the code-behind to generate the content:
On the page:
<%# Eval("SaveDate") != DBNull.Value ? GenerateContent() : string.Empty %>
In my class:
protected string GenerateContent()
{
return "Hello, World!"
}