For the following code:
<% foreach (Entities.Core.Location loc in locations){ %>
<div class="place_meta">
<img src="~/static/images/stars/star_25_sml.gif" runat="server" class="star_rating"/>
</div>
<% }; %>
I would like to display the star rating image for each location object displayed. However, only the first location object's star rating is displayed. For the rest, the image tag becomes <img class="star_rating" />
Am I missing anything in the syntax that allows the ability to have controls with runat=server within a foreach on the aspx page? This is with ASP.net 2.0.
I could possibly call a function in the codebehind or a display class to absolute map the URL but I am very curious if there is a solution to this problem.
Just for clarifications, the path to the image could possibly be different for each location object.
You can't use server controls within an inline loop, because ASP.NET needs to be able to uniquely identify each control to process it. The for... loop prevents this. The easiest and cleanest way is to use a Repeater control and bind your collection to it (in code-behind). Set the URL property in the bind event handler, and maintain a counter variable while binding, to check if you're at the first item or not.
Edit: I've played around with this some more, and found that if you assign an ID attribute, all looped instances get the same ID, but ASP.NET only recognizes the first control found. This would be an extremely dirty way to set properties on the first instance only. Please don't write code like this.
Unless you're using MVC, you might find a Repeater Control more useful in this situation.
If I remember correctly, you can use a source of data (your locations in this instance) and then loop through and set each image.
I don't know if your code is supposed to work, but this one is ;-)
<asp:Image ImageUrl="~/static/images/stars/star_25_sml.gif" runat="server" class="star_rating" />
Perhaps it's what you are looking for.
EDIT: looking at the code of System.Web.UI.HtmlControls.HtmlImage you can see that the src attribute is removed after the (first) processing. This may be the reason why you can get just the first URI correct with your code.
I would remove the runat="server" attribute and reference the image using a relative path (or the full path) instead of using the tilde.
EDIT: FWIW, #miies idea fits the ASP.NET paradigm AND is an example of why I'm switching to ASP.NET MVC.
Related
I recently started working with some legacy ASP.NET stuff, and I've run into an interesting problem:
I've got a table displaying a few values, some of which are evaluated in C# server-side. They all work correctly. Then all of a sudden...
<td><asp:Label ID="Label2" runat="server" class='<%=SevenDayThresholdTooHighOrLow%>'><%=ChgFromSevenDaysAgoInfo%></asp:Label></td>
ChgFromSevenDaysAgoInfo is evaluated properly.
SevenDayThresholdTooHighOrLow is rendered as a string inside of the class quotations. That is
class="<%=SevenDayThresholdTooHighOrLow%>".
In the code-behind file, the two variables are declared in the same scope, and assigned values pretty much one after the other. My Visual Studio doesn't complain about not finding certain variables in code like it would if the property did not exist.
What other factors could be influencing this oddity? What could I have missed?
Thank you very much for your help, everyone!
Eli
EDIT: I took a look at what is the use of Eval() in asp.net and tried to set my tag up that way (class='<%# Eval("SevenDayThresholdTooHighOrLow")%>'), unfortunately to no effect.
That class attribute probably isn't being evaluated for server-side code, likely because class isn't a property of Label. (Label isn't an HTML element, it's a server-side control. So instead of HTML attributes it uses object properties.)
There's a CssClass property, you might try that instead. But even then the approach is different because the system may still not attempt to evaluate server-side code injected into already server-side components. Still, worth a try.
What should definitely work is setting the CssClass property in the code-behind:
Label2.CssClass = SevenDayThresholdTooHighOrLow;
If you want to keep this out of code-behind (and who could blame you?) then another approach could be to replace the server-side control with an HTML element entirely. The idea being that if properties on this control aren't otherwise being set in server-side code, then does it really need to be a server-side control? If I remember correctly, a Label emits as a span:
<span class="<%=SevenDayThresholdTooHighOrLow%>"><%=ChgFromSevenDaysAgoInfo%></span>
You can't do that in just the markup code. You can't use server tags in a server control. You could use a data binding tag, but then you would need to trigger the data binding from the code behind anyway.
Just set the attribute from the code behind:
Label2.CssClass = SevenDayThresholdTooHighOrLow;
OK, up front I need to say that I've been coding C# and .NET off and on since Wednesday a week ago. Just trying to figure out enough to fix some scripts provided by a 3rd party. So I'm flying blind here.
I've got a .aspx file (ie, prototype HTML) that contains some tags that need to be dynamically modified from the Page_Load method in the corresponding .cs file. I'd like to do the modification with minimal tear-up of the files involved.
The tags I need to modify are asp:Label, asp:ImageButton, and div. The first two I think I know how to modify, by referring to the IDs in the .cs and setting the associated attributes. But I can't find an "asp:" equivalent of div, nor any obvious way to modify it without that "asp:" equivalent. I could alternatively use a <style>, but I can't find any way to generate that into the HTML stream (though I see hints here and there). I have the Evjen/Hanselman/Rader ASP.NET book, but though it contains some stuff that seems headed in the right direction, that stuff uses HtmlTextWriter which doesn't seem to be the right interface for use in Page_Load.
So, any clues? I need primarily need to modify the style property inside the div.
You can just create an HtmlGenericControl by using
<div runat="server" id="something"></div>
in your code-behind
something.Attributes["style"] = "style it up";
The ASP.NET control equivalent would be an <asp:panel>, but depending on your version, panel used to (1.1) spit out <table>'s for certain browsers.
Basically I want to load a HTML document and using controls such as multiple check boxes which will be programmed to hide, delete or show HTML elements with certain ID's. So I am thinking I would have to set an inline CSS property for visibility to: false on the ones I want to hide or delete them altogether when necessary.
I need this so I don't have to edit my Ebay HTML templates in dreamweaver all the time, where I usually have to scroll around messy code and manually delete or add tags and their respective content. Whereas I just want to create one master template in dreamweaver which has all the variations that my products have, since they are all of the same genre with slight changes here and there and I just need to enable and disable the visibility of these variants as required and copy + paste the final html.
I haven's used Windows Forms before, but tried doing this in WebForms which I do know a bit. I am able to get the result that I want by wrapping any HTML elements in a <asp:PlaceHolder></asp:PlaceHolder> and just setting that place holders visibility to false after the associated checkbox is checked and a postback occurs, finally I add a checkbox/button control that removes all the checkboxes, including itself etc for final html. But this method seems just like too much pain in the ass as I have to add the placeholder tags around everything that I need control over as ordinary html elements do not run at server, also webforms injects a bunch of Javascript and ViewState data so I don't have clean HTML which I can just copy after viewing the page source.
Any tips/code that you can suggest to achieve the desired effect with the least changes required to existing HTML documents? Ideally I would want to load the HTML document in, have a live design preview of it and underneath have a bunch of well labelled checkboxes programmed to hide, delete or show elements with certain ID's.
Thanks...
<table runat="server" id="tblMain">
<tr runat="server" id="tr1">
<td runat="server" id="tdName">
dummy name
</td>
<td runat="server" id="tdSurname">
dummy surname
</td>
...
you can use tdSurname.visible = "false"; or tdSurname.Style["Visibility"] = "Hidden";
Take a look at the library Html Agility pack
i think this will work for you :
HtmlControl ctl = new HtmlGenericControl( "div" );
ctl.visible = false;
Have you considered using JQuery? If the elements you want to show/hide have fixed IDs then this might be a quick and dirty solution.
I have an .aspx page setup. I have a lot of placeholders that need to be replaced. First name, last name, city, state, etc, etc. How do I go about doing this in an efficient manner?
Drop a bunch of...
<asp:Label runat="server" id="Label_FirstName" Text="" />
...everywhere?
Or is there a way to use the data binding syntax in the normal page area:
<% FirstName %>
Thanks in advance!
Note that
<asp:Label runat="server" id="Label_FirstName" Text="" />
will escape your strings (for example, replace < and > with < and >), but
<%= FirstName %>
will not. If that's your intention that's fine then, but be aware that you might open a channel for XSS attacks. To escape your strings properly, you might want to have
<%= System.Web.HttpUtility.HtmlEncode(FirstName) %>
instead.
You can certainly use:
<%= FirstName %>
Where FirstName is a property of the page. It doesn't necessarily have to be a property in the class, you can access pretty much anything from that line.
Update: As DrJokepu pointed out, if the data you are displaying is coming from user input, then it opens a XSS vulnerability. As was pointed out you use HtmlEncode to avoid that, in that case a more short syntax would be:
<%= Server.HtmlEncode(FirstName) %>
And if you have a base page, you can get define a method and get away with:
<%= HtmlEncode(FirstName) %>
If you go with asp.net labels, do EnableViewState = false where appropiate, so you avoid sending/receiving unnecessary viewstate.
For formatting use ids/css classes, and have the styles in a css stylesheet. The css can be cached by the browser regardless of whether the content is dynamic.
For lists of info, you can use ListView or Repeaters and still control the specific html that will be sent over the wire.
You can definitely use ASP-style tags (<%= %>) but I would argue that your first approach is cleaner and easier to maintain. When you use the ASP-style tags you will not be data binding, rather you will have access to all of the members (including fields, properties, and other methods) of the Page.
So both approaches will work if FirstName is a field or property on the Page you are working on. I personally find the control-based approach better but to each their own.
I like using labels as it is easier to mess about with colors, fonts, bolding ect... to display errors or draw the users attention to certain text.
I usually just have a set-up method in the codebehind.
if(!Page.IsPostBack)
SetupForm();
SetupForm()
{
Label_FirstName.Text = firstName;
}
You can use a bunch of labels or the Substitution control or even Literal Text if you want more control over the HTML.
You can use code in your markup like:
<%=this.FirstName%>
This will result in a property on your page called FirstName to be called and the return value from it to be placed inbetween the label.
It depends on the context in which you'll be using them. Generally using the asp:label controls is fine as you'll be able to access them from the codebehind on your page. The databinding method is generally used from within a databound control like a DataGrid or Repeater.
The real problem with the databinding method is that there isn't very good IDE support for this. To get it to work you have to have a property on your page class that you need to populate in the code behind, but if the property name changes, you'll also have to make sure you update your aspx page. If you use the labels method, the IDE will detect if there is a change in the label name, or if it has been deleted altogether and give you a compile time error.
Alternatively you could use jQuery to populate your data and just use spans as your placeholders. Be aware tho that jQuery requires a bit of a different way of thinking about your pages as it's using javascript to populate your fields.
My rules of thumb are:
If I'm labeling an input control, I use a Label so that I can set the AssociatedControlID property.
Otherwise I use a Literal or Localize control. I generally don't style Labels directly, so I don't need the extra markup they generate in other situations.
So, in your situation I'd probably use the Literal control.
Jeff Atwood explored the subject at Coding Horror and found out that performance just doesn't matter...
NOTE: it seems like Jeff posts have to be taken with a grain of salt, after all... sorry for rushing in the answer without reading the comments
Try this:
<%= FirstName %>
I am trying to wrap my head around the control infrastructure to understand which ones ASP.NET maintains view state for.
There are these regular HTML controls ex:
<input type="radio" checked="checked"/> -> I understand these do not have viewstate
Then there are HTML controls with runat="server"
<input type="radio" checked="checked" runat="server"/> -> Does the viewstate get maintained between postbacks?
Then there are ASP.NET controls
<asp:TextBox id="txtMyText" runat="server"/> -> I understand these do have viewstate
We have a few custom controls that inherit HtmlTextBox
<myPrefix:myTextBox id="txtMyText" runat="server"/> -> Is this the same as type 2 above?
Is it safe to assume that any control with runat="server" tag will have viewstate maintained?
There are 3 types of controls, the standard HTML elements like , HTML server controls which have the runat=server tag added, and full web controls. Only the web controls have viewstate maintained.
When we were having problems with viewstate I started using the Viewstate helper software from Binary Fortress http://www.binaryfortress.com/aspnet-viewstate-helper/
It gives you a real insight into what's going on - as well as helping with viewstate related performance issues you can decode the viewstate with one click and see what is actually in there - so you get to understand what controls are using viewstate and which aren't, and exactly what they are storing in there.
Also, something nobody else has mentioned is ControlState. This came along with ASP.NET 2 and the theory is that the important stuff that is necesssary for a control to function goes in the control state, and the data etc in the viewstate, so you can switch off the viewstate and bind the data to your control on every postback and the control still basically works using controlstate. I say "theory" because in practice the implementation seems patchy. When you look into the dropdownlist code using reflector for example this isn't properly implemented. This may have changed with later releases of the framework, I'm not sure. Lots of info on controlstate out there if you search for it, I just thought I'd mention it.
afaik no, that HTML controls are not designed to maintain anything in the viewstate, if you care about it, take the webcontrols.
Anything you put on your page's view and add the runat="server" will have the viewstate maintained.
As for dynamically added controls, it depends on when and how you add the control to the control tree. Check out the accepted answer to this question, but also check out my question here.