A simple question, I think:
I want to put a tag into an ASP.NET app I've been asked to maintain, so I'm coming at this from a newbie point of view just tinkering around the edges without knowing a lot.
I wrote an old ASP application back in 1998, so I am just running on memory...
How do I write some output to the webpage?
I know I can use an
<asp:label id="blah">
but then I need to define a Label blah; in my code behind and then assign it.
I believe that I can put in-place:
<% Response.Write("sometext"); %>
and that will write sometext in the location within the page. (Am I correct?)
Lastly, I remember there was a syntax to the effect of
<%= "some string" %>
but I can't find the documentation on it, to say either it is deprecated, unadvised, or the rationale for such a decision.
I have tried googling for "ASP.NET grammar" but I can't even find a good description that "<%=" even exists, though it is mentioned in a few blogs.
For something simple, like inject the global version number, or the current date, then I can't see anything particularly wrong with in-place composition - it would save me defining 15 labels and having to initialise them all - though perhaps the asp:label approach could reference one global instance of a label?
Just asking for opinions on good practices :)
<%= string %> is perfectly valid ASP.NET syntax. The reason you will often find references to problems with using that is people use <%= (equivalent to Response.Write) when they should use <%# (for databinding) or vice-versa.
For example, we use it very extensively in our content managed site, where we pull in values from a global settings repository:
<%= SiteContext.Current.GetSetting("SiteTitle") %>
MSDN:
MSDN entry on <%= (this is under the JScript.NET section but still applies)
MSDN entry on <%#
Some others suggest <%= is not a "best practice" or a very good approach, but I strongly disagree with that sentiment. For an MVC-ish type site (especially a site that is template- or view-driven in some way), the most direct approach is frequently more effective than using server controls.
Just be mindful that when you use an <asp:Label /> it renders the .Text inside the <span> tag whereas an <asp:Literal /> adds no extraneous HTML to the string passed to it.
For example, if you were building a content management system and wanted to display user-driven HTML, a Label control would not correctly display the output from a WYSIWYG type rich textbox whereas a Literal control is the appropriate choice.
The <%= %> is the late-bound equivalent of the Literal's .Text property. The only difference here is when the value is placed in the page (aside from obvious syntax and separation of concerns paradigm) during the course of the page lifecycle.
Since the .Text property is on a control inherited from WebControl, it can be set/read/manipulated during any of the events following the control's Load event (wherever/whenever you load the control inside the page), but the <%= %> text cannot be directly read/used/manipulated by the code-behind without referencing some other control to get to it (like a containing div's InnerHtml property).
There are lots of options. You could use a single label, and string concatenate all the data you want displayed in that location.
You could create a user control with the layout you want and assign values that way.
You could inject it directly with response.write or the <%= %> syntax
You could create an HtmlGenericControl in your code behind (it's a div), add some text to it, and inject it into the pages controls collection.
Whatever you pick, try and go with the existing style of the coded page.
Look up the term "render blocks" for the <% %> syntax.
How about using
<asp:Literal id="z" text="goofy" runat="server" />?
Labels are usually used with forms.
You can also take full control of the rendering of your pages and controls and compose whatever you need to. You control the HTML, the order of rendering your controls, etc...
Go with the <asp:label /> (or a literal control if you want to customize some html in the content). Seriously. I'ts not that hard: when you put label in your markup visual studio will create it in the code-behind for you, so there's no extra work involved.
You could use the <%= "some string" %> syntax in web forms, but there can be issues when mixing that with the asp controls and there's a good reason new frameworks moved away from mixing logic like that in with your markup.
Related
When working with markup if I want to include some content conditionally, I use a placeholder in a normal way:
<asp:Placeholder Visible=<%# IsExpired %>
<span>Prolong your subscription</span>
</asp:PlaceHolder>
Also I can use if-directive:
<% if(IsExpired) {%>
<span>Prolong your subscription</span>
<% }%>
I prefer using the first one just because it does not make my markup messy. And what's the best way to conditionally include content? From the performance point of view, are they similar?
native HTML tags are always faster than rendering server controls as there is no time spent for rendering them
I think there is hardly anything to do with performance whether way you choose here. But actually you may use the following code:
<asp:Label runat="server" Visible=<%# IsExpired %>
Prolong your subscription</asp:Label>
instead the other two. This could make it look more straight-forward.
I'd never use C# code in Web Forms view. In addition I will avoid setting the Visible property in the markup and I will set it in the code behind on some event.
phWhatever.Visible = IsExpired;
Quite often you can avoid creating the IsExpired property.
Of course what #Johnny suggested is correct. If you need to hide what is effectively only one control you hide the control directly.
MSDN documentation states with regard to the ClientIdMode:
Static The ClientID value is set to the value of the ID property. If the control is a naming container, the control is used as
the top of the hierarchy of naming containers for any controls that it
contains.
source: http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode%28v=vs.100%29.aspx
However, i am not finding the "top of the hierarchy" business to be the case. For example, I have a usercontrol:
<uc1:WidgetsListControl runat="server" id="WidgetsListControl" ClientIDMode="Static" />
For good measure, I set the clientidmode in the control source as well although I'm not sure which one is needed:
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="WidgetsListControl.ascx.cs" Inherits="WebApplication1.WidgetsListControl" EnableViewState="false" ClientIDMode="Static" %>
Within the user control, I have a textbox:
<asp:TextBox ID="testTextBox" runat="server" />
My expectation is that the text box would be named something like WidgetsListControl$testTextBox
However what I find upon view source is:
<input name="ctl00$MainContent$WidgetsListControl$testTextBox" id="testTextBox" type="text"/>
What am I missing? Is there a way to achieve what I'm looking for (shorter ids) without setting 'static' on every control within the user control?
EDIT:
Actually after looking closer, I am finding that the ID attribute is working as described in the MSDN - however the name attribute is still the full concatenation of the naming-container hierarchy.
Given a site of high complexity, the names and IDs of these controls start to take up the majority of the bandwidth (markup size). I can't seem to find any good workaround to slim down the markup in this regard.
You must have this control within a Panel or something with runat="server" and the custom control itself is a naming container for its children. If you want identifiers to be how you name them with no change, you'll want to use the Predictable (IIRC) client id mode.
Note: though looking at the documentation for Predictable this doesn't seem to be the case, I'm sure it's what I've always used to get 'clean' .NET identifiers in ASP.NET.
Further, if you want to apply the ClientIDMode globally, then specify it in the web.config file in the attribute of the <pages> element.
ClientIdMode="Static" does work as described by Microsoft.
Make sure your looking at the id in the generated source, not the name.
That's the mistake I made.
I am a asp .net beginner. I want to use some objects created at Site.Master.cs in Site.Master. Is there an easy way to do it?
I know how to do it in MVC(by using view(the object)). But how can i do it in normal ASP .net web application?
I don't understand what exactly you want to do.
If you want to insert some string into tag's title you can insert the following thing in SiteMaster.master file:
<img src="<%= Page.ResolveUrl("~/") %>images/logo.png">
instead of:
<img src="images/logo.png">
In the first case there will be calculated the path from the root of your application. In the second case there will be relative link. This is because server will CALCULATE the value of Page.ResolveUrl("~") function and will WRITE it in src tag.
You can do the same thing with any other methods, classes if you defined them properly. But I wouldn't recommend you to implement complicated logic in .aspx files (or .master files). Because you can end up with many difficulties with testing and styling such application.
There are other server tags:
<% %> - an embedded code block is server code that executes during the page's render phase. The code in the block can execute programming statements and call functions in the current page class. Description and examples
<%= %> - most useful for displaying single pieces of information. Description and examples
<%# %> - data binding expression syntax. Description and examples
<%$ %> - ASP.NET Expression. Description and examples
<%# %> - Directive Syntax. Description and examples
<%-- --%> - Server-Side Comments. Description and examples
<%: %> like <%= %> - But HtmlEncodes the output (new with Asp.Net 4). Description and examples
Another way: you can use JSON to send some data to the client and then process it with javascript. Take a look at this project.
If the #Page directive in your .aspx file has Inherits="XYZ" where XYZ is the class declared in your .cs file, you can simply add a protected field to your class and assign a value to it. You'll be able to access it in the .aspx file just by using its name.
You can also use HttpContext.Items property to keep objects during a single request:
HttpContext.Current.Items["SavedItem"] = "hello world";
And use it in page:
<%= ((string)Context.Items["SavedItem"]) %>
Any public or protected property or method in Site.Master.cs will be accessible from Site.Master.
but how to invoke c# code in aspx ?
There are several ways, including the <%= %> construction, and databinding syntax.
It would help if you explained what you're trying to achieve.
In ASP.NET, what functions are allowed inside the <%# %> tags? I frequently use Databinder.Eval(), and I know some basic things like CStr(), but where can I find a complete list with documentation? I would look myself, but honestly I don't even know what the name of the <%# %> tags are.
It's funny that nobody really knows what these are called - I think in the ASP.NET MVC team they call them Code Nuggets. Others call them Code Rendering Blocks.
Anyway, this is essential reading: http://quickstarts.asp.net/QuickstartV20/aspnet/doc/pages/syntax.aspx
Here is some specific info on the <%# Data Binding Syntax: http://msdn.microsoft.com/en-us/library/bda9bbfx%28v=VS.100%29.aspx
And this helped me understand the Eval voodoo: http://weblogs.asp.net/rajbk/archive/2004/07/20/what-s-the-deal-with-databinder-eval-and-container-dataitem.aspx
Anything that is in scope. E.g. public/protected methods on your page, public methods in some referenced namespace/class, etc. In addition to things that are related to the current NamingContainer you're within.
This is my layout template (ascx without code behind)
<%# Control Language="C#" AutoEventWireup="true" Inherits="ws.helpers.LayoutUC" %>
<div>blah blah blah</div>
<ws:Panel runat="server" ID="left"></ws:Panel>
<ws:Panel runat="server" ID="main"></ws:Panel>
<ws:Panel runat="server" ID="right"></ws:Panel>
Modules will be added into ws:Panel later.
I also allow my user create their own ascx file to custom their page layout. And because of this i do a string replace all dangerous part like script tag (runat="server"), all asp.net html tag, <%, <%#, <#.... from their custom.
Im not worry about XSS, so dont comment on it, and ask why?
I want know your thinking about this. Is is safe? Is it scalable? Is it standard or a bad way?
Have a look at the INaminingContainer Interface http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx.
<asp:YourControl>
<LeftColumn>
<asp:Literal ID="literal1" runat="server" Text="User created literal" />
</LeftColumn>
</asp:YourControl>
In the .ascx from the users, they register your control and insert asp.net code into properties. In the 'YourControl' class you create placeholders and insert the markup set to a specific property into these placeholders. (e.g. everything between <LeftColumn> and </LeftColumn> will the inserted into
<asp:Placeholder ID="PlaceholderLeftColumn" runat="server"/>
Edit: I summed some of the TemplateContainer issue up and posted it here: http://www.tomot.de/en-us/article/2/asp.net/how-to-create-an-asp.net-control-that-behaves-as-a-template-container-to-nest-content-via-markup
You are allowing user-uploaded content; this is inherently unsafe and there are whole books dedicated to best practices. Given that you are doing it anyway, as long as you make sure you scrub the input, is it scalable? You are allowing creation of user-uploaded files on your site. How many will there be? How many users? What about load-balancing? This solution will not scale for many users, files, or servers.
It sounds like you are trying to create a simple CMS. Why not use one that exists currently, or adopt parts of an open source solution?