One of the greatest benefits I’ve found in simple web output in ASP.NET is the GridView. I regularly use it to display data from objects or databases where the output can simply be shown in a grid form (similar to instances where I would deliver a read-only spreadsheet).
I attach the GridView to the <asp:PlaceHolder /> inside of a <form /> on the aspx page:

A simple, bulk method of getting the data into the GridView is with the GridView.DataSource property.
A GridView.DataSource must be either an IListSource, IEnumerable, or IDataSource.
A natural partner to the GridView.DataSource property is the System.Data.DataSet.
Example:
Using the WebService located at: http://www.holidaywebservice.com/Holidays/US/USHolidayService.asmx .
I chose this WS, because it returns a DataSet (easy example).
1: using System;
2: using System.Collections.Generic;
3: using System.Data;
4: using System.Linq;
5: using System.Web.UI.WebControls;
6:
7: using WS_HOLIDAY;
8: public partial class _Default : System.Web.UI.Page
9: {
10: protected void Page_Load(object sender, EventArgs e) {}
11:
12: public void ShowReport()
13: {
14: GridView gvHolidays = new GridView()
15: {
16: HorizontalAlign = HorizontalAlign.Center,
17: GridLines = GridLines.Both,
18: BackColor = System.Drawing.Color.FromName("#CCCCCC"),
19: DataSource = (new USHolidayService()).GetHolidaysForYear(2011)
20: };
21:
22: holder.Controls.Add(gvHolidays);
23: gvHolidays.DataBind();
24: }
25: }
Result:

If the DataSource is to be a result of a LINQ query, the GridView will automatically choose the Property Names used in the return value (for known types with Properties).
If the returned type is Anonymous, you must supply the declarator that will be used a the Property Name as shown below.
(This will also work if you have a known type, but want to change the property names to be more appropriate.)
(This will also work if you have a returned object that used Fields instead of Properties):
Using Linq to Objects:
1: using System;
2: using System.Collections.Generic;
3: using System.Data;
4: using System.Linq;
5: using System.Web.UI.WebControls;
6:
7: public partial class _Default : System.Web.UI.Page
8: {
9: protected void Page_Load(object sender, EventArgs e) {}
10:
11: public void ShowReport()
12: {
13: //////////////////////////////////////////////////////
14: // simple func to parse a string by space and period
15: Func<string, string[]> WordParse = s =>
16: {
17: return s.Split(" .".ToCharArray(),
18: StringSplitOptions.RemoveEmptyEntries);
19: };
20:
21: //////////////////////////////////////////////////
22: // some random data representing a data source
23: List<string> lst_strData = new List<string>()
24: {
25: "This Is The Way We Funk With You",
26: "Open up your funky mind and you can fly.",
27: "Listen while I tell you of the clones.",
28: "You can't miss what you can't measure.",
29: "Hard as steel and still gettin' harder."
30: };
31:
32: //////////////////////////////////////////////////
33: // Create a GridView with some default settings.
34: GridView gv = new GridView()
35: { //top-level atributes can be auto populated.
36: HorizontalAlign = HorizontalAlign.Center,
37: GridLines = GridLines.Both,
38: BackColor = System.Drawing.Color.FromName("#CCCCCC"),
39: };
40:
41: //////////////////////////////////////////////
42: // All other attributes are done separately.
43: // These are just my personal preferences
44: gv.RowStyle.HorizontalAlign = HorizontalAlign.Center;
45: gv.AlternatingRowStyle.BackColor = System.Drawing.Color.FromName("#EEEEEE");
46: gv.HeaderStyle.Font.Bold = true;
47: gv.HeaderStyle.BackColor = System.Drawing.Color.FromName("YELLOW");
48: gv.Font.Size = 9;
49: //
50: long lngRowNum = 0; //<-used to make the row counter
51:
52: gv.DataSource =
53: from str in lst_strData
54: let arr_str = WordParse(str)
55: where (arr_str.Count().Equals(7))
56: select new //ANONYMOUS TYPE
57: {
58: // ** Anonymous type members **
59: // These become the column names in the GridView!!!
60: NUM_SENTENCES = ++lngRowNum, //<-Auto-incrementing row counter
61: WORD1 = arr_str[0],
62: WORD2 = arr_str[1],
63: WORD3 = arr_str[2],
64: WORD4 = arr_str[3],
65: WORD5 = arr_str[4],
66: WORD6 = arr_str[5],
67: WORD7 = arr_str[6]
68: };
69:
70: holder.Controls.Add(gv);
71: gv.DataBind();
72: }
73: }
Result:

If the code does not supply the declarator/Property Name, an error will be generated:
Invalid anonymous type member declarator. Anonymous type members must be declared with a member assignment, simple name or member access.

Please let me know if this does not make any sense :)