ASP.Net - looping/conditional statements in Layouts
Coming from PHP and more specifically many of the MVC frameworks out their, I've been use to using basic foreac开发者_JAVA技巧h
and if
constructs in PHP directly in the layout. Now that I'm learning ASP.NET I'm presented with more proprietary concepts like a ListView
to control looping, etc...
So to give an example of what I want to do..
<div id="container">
<h1 class="header">Title</h1>
<% For Each item In ItemsCollection %>
<% If item.Name IsNot Nothing %>
<h3>This is the layout for <%= item.Name %></h3>
<% End If %>
<p><%= item.Content %></p>
<% Next %>
</div>
Then there isn't a lot I have to handle in the Code Behind file... besides making ItemsCollection
available.
Is This considered Bad Practice? Should I spend the time learning the proprietary controls for ASP.NET? Are there specific limitations of this approach?
This may be subjective, but there are tons of documentation about why the standard controls such as the ListView were created. The primary benefits is separation of concerns, and avoidance of "spaghetti code", which is exactly what your sample is.
I believe that if you're going to be developing in .NET is is well worth your time to learn the controls, and the background for these controls. A lot of the power, productivity, code clarity, and ease of .NET development is hinged around such design principles. Whether they are "Correct" or "right" compared to other environments is debatable.
All of the above beside...
The short version is that if you're going to be developing in .NET using the WebForms model, you should code like a .NET WebForms developer, if for no other reason than that it's likely that a .NET WebForms developer will need to maintain your code some day. We've all been trained to expect certain things, and stuff like this drives us nuts when maintaining other people's code.
Edit
Of course, if you go with ASP.NET MVC, you'll be in your comfort zone and my opinion will not apply.
There's no need to embed code and markup like this in ASP.NET (With some exceptions ;)).
Instead, you can have a ListView
control that you can bind to a DataSource; for example:
<h3>ListView Example</h3>
<asp:ListView ID="VendorsListView"
DataSourceID="VendorsDataSource"
DataKeyNames="VendorID"
OnItemDataBound="VendorsListView_ItemDataBound"
runat="server">
<ItemTemplate>
<tr runat="server">
<td>
<asp:Label ID="VendorIDLabel" runat="server" Text='<%# Eval("VendorID") %>' />
</td>
<td>
<asp:Label ID="AccountNumberLabel" runat="server" Text='<%# Eval("AccountNumber") %>' />
</td>
<td>
<asp:Label ID="NameLabel" runat="server" Text='<%# Eval("Name") %>' /></td>
<td>
<asp:CheckBox ID="PreferredCheckBox" runat="server"
Checked='<%# Eval("PreferredVendorStatus") %>' Enabled="False" />
</td>
</tr>
</ItemTemplate>
</asp:ListView>
<!-- This example uses Microsoft SQL Server and connects -->
<!-- to the AdventureWorks sample database. Add a LINQ -->
<!-- to SQL class to the project to map to a table in -->
<!-- the database. -->
<asp:LinqDataSource ID="VendorsDataSource" runat="server"
ContextTypeName="AdventureWorksClassesDataContext"
Select="new (VendorID, AccountNumber, Name, PreferredVendorStatus)"
TableName="Vendors" Where="ActiveFlag == @ActiveFlag">
<WhereParameters>
<asp:Parameter DefaultValue="true" Name="ActiveFlag" Type="Boolean" />
</WhereParameters>
</asp:LinqDataSource>
Taken from here.
UPDATE: As far as conditional statements, you can handle the ItemDataBound event:
protected void VendorsListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
string vendorID= (string)DataBinder.Eval(dataItem, "VendorID");
// ...
}
}
If you go with the vanilla ASP.NET framework, your example is not best practice and you should stick with the server-side control model. ASP.NET was designed to be used primarily as a server-side control model. What you describe more closely matches traditional ASP pages.
For example, a Repeater
control would match your example code perfectly.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.aspx
Rough example:
Markup:
<asp:Repeater id="Repeater1" runat="server">
<HeaderTemplate>
<div id="container">
<h1 class="header">Title</h1>
</HeaderTemplate>
<ItemTemplate>
<h3>This is the layout for <%# DataBinder.Eval(Container.DataItem, "Name") %></h3>
<p><%# DataBinder.Eval(Container.DataItem, "Content") %></p>
</ItemTemplate>
<FooterTemplate>
</div>
</FooterTemplate>
</asp:Repeater>
Code behind:
protected void Page_Load(Object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// create or retrieve some bindable datasource
// ArrayList values = ....
Repeater1.DataSource = values;
Repeater1.DataBind();
}
}
That is a matching server side control model to your example. The Repeater
will by design iterate through your item collection and create the same end result. It basically spits out the header template, iterates your collection using the item template, and then spits out the footer template. There are lots of other options as well, this is simply a quick example.
精彩评论