<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/xsl" href="./rss/rssfeed.xsl"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>mike's web log</title><link>http://www.mikepope.com/blog/</link><description>mike pope's Web log</description><language>en-US</language><docs>http://www.mikepope.com/blog/BlogFeed.rss</docs><webMaster>mike@mikepope.com</webMaster><lastBuildDate>Tue, 21 May 2013 22:22:47 GMT</lastBuildDate><pubDate>Tuesday, May 21, 2013 10:22:47 PM</pubDate><ttl>60</ttl><item><title>Default button</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1518</link><description>One of the many cool things in ASP.NET 2.0 is that you can declaratively set a default button. This makes the pain of the various hacks (&lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=309" target="_blank"&gt;#&lt;/a&gt;) pretty much go away, bye-bye.&lt;br /&gt;&lt;br /&gt;With this in mind, I set the default button for my main blog page (yer on it right now) to be the Search button, using this syntax:&lt;pre&gt;&amp;lt;form runat="server" &lt;b&gt;DefaultButton="buttonSearch"&lt;/b&gt;&amp;gt;&lt;/pre&gt;I quick-like tested it and it worked just fine. &lt;br /&gt;&lt;br /&gt;But I soon got a complaint that when the page first opened, it was scrolling down a bit. I had a look, and sure enough. Now that I had a default button for the form, when the page loaded, it set the focus on the button, which was below the fold. That's not what I wanted.&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;DefaultButton&lt;/b&gt; attribute can be applied to containers, so to fix this, I removed the attribute from the &lt;b&gt;&amp;lt;form&amp;gt;&lt;/b&gt; tag. The box you see as Search is a &lt;b&gt;&amp;lt;td&amp;gt;&lt;/b&gt; element in a table. So within the &lt;b&gt;&amp;lt;td&amp;gt;&lt;/b&gt; element I added an &lt;b&gt;&amp;lt;asp:panel&amp;gt;&lt;/b&gt; element and set its &lt;b&gt;DefaultButton&lt;/b&gt; attribute to point to the Search button. &lt;br /&gt;&lt;br /&gt;The morals of the story are that a) setting a default button will by default (haha) also set focus, and that therefore and/or maybe b) you want to either move your default button to an appropriate location or scope it to a suitable container. (Does this make sense? Hope so.) Anyway, I humbly submit this as your tip of the day. :-) </description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1518</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1518</guid><pubDate>Thu, 01 Jun 2006 22:51:51 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1518">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1518</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1518</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1518</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Error handling in data source controls</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1496</link><description>In a comment &lt;a href="http://mikepope.com/blog/AddComment.aspx?blogid=1447" target="_blank"&gt;on another&lt;/a&gt; post about validating parameters for the &lt;b&gt;SqlDataSource&lt;/b&gt; control, someone asks about how to handle errors that might occur within the &lt;b&gt;SqlDataSource&lt;/b&gt; control -- e.g. "query timeout, SQL Server not running, mistake in query," to quote the comment. I thought it was worthwhile to promote the discussion from the comments to a separate entry. (If you read those comments, there's nothing new here for you ...)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://forums.asp.net/members/Eilon.aspx" target="_blank"&gt;Eilon&lt;/a&gt; confirmed that the data source controls don't raise their own error events. You can trap errors like the ones listed, but you have to do so slightly indirectly. &lt;br /&gt;&lt;br /&gt;You have (at least) two choices. One is to perform data binding yourself and put the &lt;b&gt;DataBind&lt;/b&gt; call into a &lt;b&gt;try-catch&lt;/b&gt; block:&lt;pre&gt;Sub Page_Load()&lt;br /&gt;   If Not IsPostBack Then&lt;br /&gt;      Try&lt;br /&gt;          GridView1.DataSourceID = "SqlDataSource1"&lt;br /&gt;          GridView1.DataBind()&lt;br /&gt;      Catch ex As Exception&lt;br /&gt;         ' Hopefully better error handling that this ...&lt;br /&gt;         Response.Write("Error data binding")&lt;br /&gt;      End Try&lt;br /&gt;   End If&lt;br /&gt;End Sub&lt;/pre&gt;You can also catch the error in the &lt;b&gt;Page_Error&lt;/b&gt; handler (documented &lt;a href="http://msdn2.microsoft.com/en-US/library/ed577840.aspx" target="_blank"&gt;here&lt;/a&gt;). Handle the &lt;b&gt;Page_Error&lt;/b&gt; event and then redirect (using &lt;b&gt;Server.Transfer&lt;/b&gt;) to an error page. Here's the handler:&lt;pre&gt;Sub Page_Error()&lt;br /&gt;   Server.Transfer("DataBindError.aspx")&lt;br /&gt;End Sub&lt;/pre&gt;And a possibility for the target page:&lt;pre&gt;Sub Page_Load()&lt;br /&gt;   Label1.Text = Server.GetLastError.Message&lt;br /&gt;End Sub&lt;/pre&gt;This will catch &lt;i&gt;all&lt;/i&gt; unhandled errors in the page, which I guess is a good thing or a bad thing, depending.&lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1496'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1496</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1496</guid><pubDate>Mon, 08 May 2006 16:57:36 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1496">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1496</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1496</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1496</wfw:commentRss><slash:comments>3</slash:comments></item><item><title>Custom email control</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1489</link><description>For whatever reason, creating custom ASP.NET controls is something that is ... uh ... underrepresented in my skill set. As with certain other corners of the product, my theoretical knowledge outstrips my practical knowledge. So when I was messing around with a couple of things recently, I thought that they might be good practice scenarios for creating some custom controls. &lt;br /&gt;&lt;br /&gt;The thing about custom controls is that the concept is really quite easy to grasp. You inherit from, say, &lt;b&gt;WebControl&lt;/b&gt; and you override &lt;b&gt;Render&lt;/b&gt;, and you're in business. And if you're working in VS2005, the thing practically writes itself. (haha) The base control class does an amazing amount of heavy lifting and -- again, in outline -- you only need to add your control-specific logic. &lt;br /&gt;&lt;br /&gt;As happens, though, the difficulties lie in the details. I have found that to be true even with the very simple controls I've done -- there's always a gotcha or three that makes (at least for the less-experienced, like me) for a certain two-steps back type of development. Which I guess is where all the fun is.&lt;br /&gt;&lt;br /&gt;The first control I fooled around with was a "dynamic" email control. (I'm pretty sure that an email control is the first thing most people fool around with, the "Hello, World" of control development.) In my case, I wanted a control that implemented the supposed anti-email-spambot feature that I &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=800" target="_blank"&gt;learned about some time ago&lt;/a&gt;. The idea is that instead of setting the &lt;b&gt;href&lt;/b&gt; attribute in an &lt;b&gt;&amp;lt;a&amp;gt;&lt;/b&gt; tag to a &lt;b&gt;mailto:&lt;/b&gt; value, you set it to a JavaScript function that dynamically constructs the &lt;b&gt;mailto:&lt;/b&gt; value on the fly (on &lt;b&gt;onclick&lt;/b&gt; and &lt;b&gt;onmouseover&lt;/b&gt;) and assigns it to the &lt;b&gt;href&lt;/b&gt; attribute. Look, ma, nothing for the spambot to find. (At least, not for dumb spambots.) I've done this procedurally in a page, so now it was time to encapsulate the behavior into a control.&lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1489'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1489</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1489</guid><pubDate>Sun, 30 Apr 2006 14:56:56 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1489">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1489</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1489</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1489</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Web Development Tools team blog</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1486</link><description>My homies on the Web Development Tools team -- the folks who brought you Visual Web Developer and Visual Web Developer Express -- have started a &lt;a href="http://blogs.msdn.com/WebDevTools/" target="_blank"&gt;team blog&lt;/a&gt;. &lt;br /&gt;&lt;br /&gt;Cute picture, although it's kinda small. :-)</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1486</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1486</guid><pubDate>Fri, 21 Apr 2006 14:24:41 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1486">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1486</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1486</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1486</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>On code examples</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1467</link><description>In his blog, Karl Seguin has a &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2006/03/24/141760.aspx#comments" target="_blank"&gt;thoughtful rant&lt;/a&gt; (is that an oxymoron?) about code examples in documentation. He shows some examples from (whew) the Macromedia documentation for .NET.[&lt;a href='#oncodeexamples1'&gt;1&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;He finds some examples of particularly egregious bad practices, including:&lt;ul&gt;&lt;li&gt;Insecure code.&lt;li&gt;Poor error handling.&lt;br /&gt;&lt;li&gt;Non-meaningful variable names.&lt;br /&gt;&lt;li&gt;Inefficient and inelegant code.&lt;/ul&gt;In a follow-on comment, he notes one point in particular: &lt;blockquote&gt;One concern I had with the Macromedia stuff is I think (and I could totally be wrong) that there'll be a high percentage of copy/pasting. This is material focused towards developers not primarily focused on .NET (or similar languages).  They don't know that it's wrong/incomplete.  They want to get their flash app working and taking the sample to modify the connection string and select statement might be all the work they'll put into it. Why should they do any more? This does come from Macromedia after all.&lt;/blockquote&gt;We've rassled with a lot of these issues. When we write code examples, there is a constant tension, let's call it, between functionality and readability. We very much bear in mind Karl's point about copy-n-paste, one of the behaviors that defines the so-called &lt;a href="http://www.bbits.co.uk/blog/archive/2004/01/15/167.aspx" target="_blank"&gt;Mort persona&lt;/a&gt;.[&lt;a href='#oncodeexamples2'&gt;2&lt;/a&gt;]&lt;br /&gt;&lt;br /&gt;Consider database access. We went round and round about how to illustrate this. To accommodate our Morts, we would ideally offer nearly copy-n-paste examples. In that case, it would be easiest to show a) an explicit connection string, and b) explicit credentials. That would minimize the number of changes that the Mort developer would have to make, and it would reduce the cognitive burden required to get the example working. &lt;br /&gt;&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1467'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey,writing</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1467</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1467</guid><pubDate>Tue, 04 Apr 2006 21:21:08 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1467">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1467</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1467</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1467</wfw:commentRss><slash:comments>5</slash:comments></item><item><title>Mapping .rss</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1464</link><description>Having a) implemented a comments feed b) as a handler (pat self on back), I thought it would be "elegant" to deliver it as URL that ended in .rss. And so I have: the comment feed is now BlogCommentsFeed.rss. Check it out:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mikepope.com/blog/blogcommentsfeed.rss?id=1458" target="_blank"&gt;http://www.mikepope.com/blog/blogcommentsfeed.rss?id=1458&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It wasn't hard, but I had to bang on the side of the box a few times before everything was working. What it really was was a lesson in how much ASP.NET does for you under the covers. &lt;br /&gt;&lt;br /&gt;I started with a default handler (BlogCommentsFeed.ashx). The .ashx extension is, haha, handled automatically by ASP.NET; ASP.NET assumes that it's dealing with an HTTP handler. Alls you have to do is create a class that implements &lt;b&gt;IHttpHandler&lt;/b&gt;, implements a &lt;b&gt;ProcessRequest&lt;/b&gt; method, and implements an &lt;b&gt;IsReusable&lt;/b&gt; property. Using VS 2005 makes all of this trivially easy. The template in VS also adds an &lt;b&gt;@&amp;nbsp;WebHandler&lt;/b&gt; directive at the top of the file, which looks a lot like an &lt;b&gt;@&amp;nbsp;Page&lt;/b&gt; directive.&lt;br /&gt;&lt;br /&gt;Do all this and make sure the file has an .ashx extension, and you can put the file anywhere. When ASP.NET sees the .ashx extension, it knows what to do.&lt;br /&gt;&lt;br /&gt;But ASP.NET does not, of course, know what to do with an .rss extension. What I did was:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;In IIS, I mapped the .rss extension to the  C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll ISAPI. This tells IIS to hand the .rss requests to ASP.NET.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.mikepope.com/blog/images/rssmapping.gif" height='196' width='384' /&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;In ASP.NET, I edited the Web.config file and added a mapping for the handler:&lt;pre&gt;&amp;lt;httpHandlers&amp;gt;&lt;br /&gt;   &amp;lt;add verb="GET" path="blogcommentsfeed.rss" type="BlogCommentsFeed" /&amp;gt;&lt;br /&gt;&amp;lt;/httpHandlers&amp;gt;&lt;/pre&gt;This tells ASP.NET that when it sees a request for blogcommentsfeed.rss, invoke the BlogCommentsFeed class.&lt;br /&gt;&lt;br /&gt;&lt;li&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1464'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1464</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1464</guid><pubDate>Mon, 03 Apr 2006 02:31:43 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1464">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1464</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1464</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1464</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>"Express" yourself</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1451</link><description>The marketing folks at work have thunk up a contest to encourage inventive ways to use the Visual Studio/SQL Server Express Edition products:&lt;br&gt;&lt;br&gt;&lt;center&gt;&lt;table width="75%" cellpadding=4 style="border-width:1pt;border-color:black;border-style:solid"&gt;&lt;tr&gt;&lt;td align="left" valign="top"&gt;&lt;img src="http://www.mikepope.com/blog/images/made-in-express-web-icon.gif" height='70' width='70' /&gt;&lt;/td&gt;&lt;td&gt;&lt;b&gt;Made in Express Contest&lt;/b&gt;&lt;br/&gt;Do you like to use technology to build cool and useful stuff?  Do you think you could do it with Visual Studio Express and/or SQL Server Express?  Would you like $10,000 cash?  Well then we have a contest for you!  Learn more at &lt;a href="http://www.MadeInExpressContest.com" target="_blank"&gt;www.MadeInExpressContest.com&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/center&gt;&lt;br /&gt;$10,000, dang. :-)</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1451</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1451</guid><pubDate>Tue, 14 Mar 2006 11:41:58 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1451">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1451</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1451</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1451</wfw:commentRss><slash:comments>2</slash:comments></item><item><title>Validating data source control parameters</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1447</link><description>The redoubtable Eilon Lipton came up with another nice nugget of data-source-control goodness in answer to a question at work today. Here's the scenario. You are using a &lt;b&gt;SqlDataSource&lt;/b&gt; control to run a query like this:&lt;br&gt;&lt;br&gt;&lt;code&gt;Select FirstName, LastName From Employees Where EmployeeId = ?&lt;/code&gt;&lt;br&gt;&lt;br&gt;(Here, the EmployeeId field is an integer.) You want to be able to pass the EmployeeId to the &lt;b&gt;SqlDataSource&lt;/b&gt; control directly from the query string. No problem; the data source configuration wizard walks you right through setting that up. It ends up looking something like this:&lt;pre&gt;&amp;lt;asp:SqlDataSource ID="SqlDataSource1" runat="server" &lt;br&gt;   ConnectionString="&amp;lt;%$ ConnectionStrings:EmployeesConnectionString %&amp;gt;"&lt;br&gt;   SelectCommand="SELECT [FirstName], [LastNamee] FROM [Employees] &lt;br&gt;      WHERE ([EmployeeID] = @EmployeeID)"&amp;gt;&lt;br&gt;   &amp;lt;SelectParameters&amp;gt;&lt;br&gt;      &amp;lt;asp:QueryStringParameter Name="BlogID" &lt;br&gt;         QueryStringField="ID" Type="Int32" /&gt; &lt;br&gt;   &amp;lt;/SelectParameters&amp;gt;&lt;br&gt;&amp;lt;/asp:SqlDataSource&amp;gt;&lt;/pre&gt;But what if someone &lt;i&gt;(those darn users)&lt;/i&gt; passes in a query string value that's not an integer? You get one of those "Input string not in correct format" errors. &lt;br&gt;&lt;br&gt;So you want to validate that the query string value is an integer. You can do this by handling the &lt;b&gt;SqlDataSource&lt;/b&gt; control's &lt;b&gt;Selecting&lt;/b&gt; event. There, you can extract the parameter value, test it, and cancel the event (and thus the query) if something's awry. Here's one way you might check that the query string value is an integer (or integer-able, anyway):&lt;pre&gt;Protected Sub SqlDataSource1_Selecting(ByVal sender As Object, _&lt;br&gt;      ByVal e As System.Web.UI.WebControls.SqlDataSourceSelectingEventArgs)&lt;br&gt;   Dim idString As String = e.Command.Parameters(0).Value.ToString()&lt;br&gt;   Dim id As Integer&lt;br&gt;   If Int32.TryParse(idString, id) = False Then&lt;br&gt;      labelStatus.Text = "Invalid ID in query string"&lt;br&gt;      e.Cancel = True&lt;br&gt;   End If&lt;br&gt;End Sub&lt;/pre&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1447'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1447</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1447</guid><pubDate>Thu, 09 Mar 2006 23:50:36 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1447">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1447</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1447</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1447</wfw:commentRss><slash:comments>9</slash:comments></item><item><title>Missing sample code</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1446</link><description>When you read a page on MSDN, you can both rate it and enter comments. Other people can see the ratings, but the comments are not visible to all.&lt;br&gt;&lt;br&gt;Now and again we'll have a look at a topic and wonder about the ratings. (Well, we generally wonder only about bad ratings. :-) ) There have been a few that we thought were pretty useful topics that have gotten low ratings. Then when we look at the comments, we'll find out that, oh, say, the code in the topic has a bug in it. &lt;i&gt;There's&lt;/i&gt; a way to get yerself a low rating.&lt;br&gt;&lt;br&gt;And do you want a really, really low rating? How about &lt;i&gt;if you leave the sample code out altogether?&lt;/i&gt; Uh ... oops. We did this in a topic I was looking at today[&lt;a href='#1'&gt;1&lt;/a&gt;]:&lt;br&gt;&lt;br&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/yt340bh4(l=en-us,v=VS.80).aspx" target="_blank"&gt;How to: Locate the Web Forms Controls on a Page by Walking the Controls Collection&lt;/a&gt;&lt;br&gt;&lt;br&gt;The comments were surprisingly un-vicious, considering. Anyway, here's the missing code:&lt;pre&gt;' VB&lt;br&gt;&amp;lt;%@ Page Language="VB"  %&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml" &amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;head runat="server"&amp;gt;&lt;br&gt;    &amp;lt;title&amp;gt;Locate the Web Forms Controls on a Page by Walking the Controls Collection&amp;lt;/title&amp;gt;&lt;br&gt;&amp;lt;/head&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;script runat="server"&amp;gt;&lt;br&gt;    Private Sub Button1_Click(ByVal sender As System.Object, _&lt;br&gt;     ByVal e As System.EventArgs) Handles Button1.Click&lt;br&gt;        Dim allTextBoxValues As String = ""&lt;br&gt;        Dim c As Control&lt;br&gt;        Dim childc As Control&lt;br&gt;        For Each c In Page.Controls&lt;br&gt;            For Each childc In c.Controls&lt;br&gt;                If TypeOf childc Is TextBox Then&lt;br&gt;                    allTextBoxValues &amp;= CType(childc, TextBox).Text &amp; ","&lt;br&gt;                End If&lt;br&gt;            Next&lt;br&gt;        Next&lt;br&gt;        If allTextBoxValues &amp;lt;&amp;gt; "" Then&lt;br&gt;            Label1.Text = allTextBoxValues&lt;br&gt;        End If&lt;br&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1446'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey,work</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1446</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1446</guid><pubDate>Thu, 09 Mar 2006 16:54:24 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1446">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1446</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1446</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1446</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Anti-XSS library</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1437</link><description>Someone at Microsoft has posted improved versions of &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebhttpserverutilityclasshtmlencodetopic.asp" target="_blank"&gt;HtmlEncode&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemWebHttpServerUtilityClassUrlEncodeTopic.asp" target="_blank"&gt;UrlEncode&lt;/a&gt; in what they call the "Microsoft Anti-Cross Site Scripting Library V1.0." The library includes two methods that are essentially the same as the corresponding methods in &lt;b&gt;HtmlServerUtility&lt;/b&gt;:&lt;pre&gt;public static string HtmlEncode(string s);&lt;br&gt;public static string UrlEncode(string s);&lt;/pre&gt;Thus:&lt;pre&gt;String s = Microsoft.Security.Application.AntiXSSLibrary.HtmlEncode(TextBox1.Text);&lt;/pre&gt;The difference between the &lt;b&gt;HtmlUtility&lt;/b&gt; and the Anti-XSS library versions of the methods is that the former encodes only a specific a set of characters, whereas the new version encodes everything &lt;i&gt;but&lt;/i&gt; a specific set of characters. IOW, the former uses a blacklist, the latter a whitelist. In security terms, this means the new version is that much harder to get around.&lt;br&gt;&lt;br&gt;(All of this information lifted directly from the docs and samples included with the library.) &lt;br&gt;&lt;br&gt;To use the new library, download the .msi from   the &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9a2b9c92-7ad9-496c-9a89-af08de2e5982" target="_blank"&gt;download page&lt;/a&gt; and run it. The installer puts the library by default at &lt;code&gt;&lt;i&gt;x&lt;/i&gt;:\Program Files\microsoft\Anti-Cross Site Scripting Library V1.0&lt;/code&gt;. The installation includes some minimal docs, some samples, and an assembly containing the class. The easiest way to use it, probably, is to copy the assembly to the Bin folder of any app where you want to use it. Have a look at the .rtf file in the Documentation folder for a little more information than what's listed here.&lt;br&gt;&lt;br&gt;Via &lt;a href="http://larkware.com/dg5/TheDailyGrind826.html" target="_blank"&gt;Mike Gunderloy&lt;/a&gt;.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1437</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1437</guid><pubDate>Sat, 25 Feb 2006 17:03:37 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1437">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1437</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1437</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1437</wfw:commentRss><slash:comments>6</slash:comments></item><item><title>Record counts and data source controls</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1428</link><description>Someone emailed recently and asked "Using MxDatagrid [the data grid control in &lt;a href="http://asp.net/webmatrix/default.aspx?tabIndex=4&amp;tabId=46" target="_blank"&gt;Web Matrix&lt;/a&gt;], how can I easily get the number of rows returned from the issued select statement?" The guy was paging in the grid, and wanted to do an &lt;i&gt;n&lt;/i&gt; of &lt;i&gt;m&lt;/i&gt; display, where &lt;i&gt;m&lt;/i&gt; was the total number of records that the query would return.&lt;br&gt;&lt;br&gt;Perhaps surprisingly, this information does not appear to be directly exposed by the data source controls. I say surprisingly because if anyone would know how many records are in the current query, it's the data souce control. In Visual Web Developer, for example, there is no direct way to get something like the &lt;b&gt;SqlDataSource&lt;/b&gt; control to tell you how many records its most recently executed query returned. &lt;br&gt;&lt;br&gt;Slighlty oddly, Web Matrix, which introduced proto-versions of the data source controls, actually did seem to have a way to do this, albeit one that doesn't seem like it was directly designed for it. We stumbled on a way to get the &lt;b&gt;SqlDataSourceControl&lt;/b&gt; (this is Web Matrix, remember) to cough up the info using this code:&lt;pre&gt;Dim itemCount As Integer = 0&lt;br&gt;Dim dataSourceItems As IEnumerable = SqlDataSourceControl1.GetDataSource("")&lt;br&gt;Dim o As Object&lt;br&gt;For Each o In dataSourceItems&lt;br&gt;    itemCount += 1&lt;br&gt;Next&lt;/pre&gt;Needless to say, this is a hack. It relies on the heavily underdocumented &lt;b&gt;GetDataSource&lt;/b&gt; method, and who knows what that's actually for? There isn't much in the way of Web Matrix documentation. However, my correspondent was happy to report that it did work for him.&lt;br&gt;&lt;br&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1428'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>whidbey,aspnet</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1428</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1428</guid><pubDate>Thu, 16 Feb 2006 01:37:45 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1428">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1428</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1428</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1428</wfw:commentRss><slash:comments>1</slash:comments></item><item><title>DropDownList in a FormView control</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1423</link><description>Another in an apparently relentless series of posts about trying to see how much can be done with the new data controls in ASP.NET 2.0 without writing code. It's pretty easy to take advantage of the code hooks we all know and love, like the &lt;b&gt;ItemDataBound&lt;/b&gt; event in the &lt;b&gt;DataGrid&lt;/b&gt; control (&lt;b&gt;RowDataBound&lt;/b&gt; in the &lt;b&gt;GridView&lt;/b&gt; control). which lets you do a whole lotta stuff. A more interesting challenge is to see what you can do with no code at all.&lt;br /&gt;&lt;br /&gt;A question came up several times the other day about using a &lt;b&gt;DropDownList&lt;/b&gt; control inside a (e.g.) &lt;b&gt;FormView&lt;/b&gt; control. It's a pretty common scenario -- people want to be able to edit values by picking a value from a list:&lt;br /&gt;&lt;br /&gt;&lt;img src="http://www.mikepope.com/blog/images/FormView_DropDown.gif" width="284" height="218" /&gt;&lt;br /&gt;&lt;br /&gt;In this example, the &lt;b&gt;FormView&lt;/b&gt; control displays data from the Northwind Products table. One of the fields is CategoryID. The easy way to edit the CategoryID field is to pick from a list of categories. So the &lt;b&gt;FormView&lt;/b&gt; control's templates contain a &lt;b&gt;DropDownList&lt;/b&gt; control that displays records from the Category table. Make sense?&lt;br /&gt;&lt;br /&gt;Once again the clever &lt;a href="http://forums.asp.net/user/Profile.aspx?UserID=73" target="_blank"&gt;Polita&lt;/a&gt; (who owns the &lt;b&gt;FormView&lt;/b&gt; control) was able to whip this thing out on her whiteboard in about 60 seconds. This, I should probably add, after I myself had, mmm, &lt;i&gt;not&lt;/i&gt; been able to do that. &lt;br /&gt;&lt;br /&gt;The first job is to display the category name in the read-only &lt;b&gt;ItemTemplate&lt;/b&gt;. You can do that a couple of ways. One way would be to create a Select statement that joined Products to Categories and thereby gave you access to CategoryName. You could then display it using a &lt;b&gt;Label&lt;/b&gt; control or something.&lt;br /&gt;&lt;br /&gt;Here I practiced, so to speak, using the &lt;b&gt;DropDownList&lt;/b&gt; control. The &lt;b&gt;FormView&lt;/b&gt; and &lt;b&gt;DropDownList&lt;/b&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1423'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1423</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1423</guid><pubDate>Wed, 08 Feb 2006 19:44:05 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1423">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1423</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1423</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1423</wfw:commentRss><slash:comments>27</slash:comments></item><item><title>GridView and dynamic data sources</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1419</link><description>Now and again you want to bind the &lt;b&gt;GridView&lt;/b&gt; control not to a data source control or dataset, but just to some data you happen to have hanging around. A typical example, for example, might be that you extract or generate the data at run time -- i.e., it's not in a data store -- and then want to display it. &lt;br /&gt;&lt;br /&gt;As the docs say, you can bind data control to anything that implements IEnumerable. All well and good, but it isn't always obvious &lt;i&gt;how&lt;/i&gt; to bind to some arbitrary but IEnumerably-implementing data structure.&lt;br /&gt;&lt;br /&gt;The question came up at work the other day, and the awesome &lt;a href="http://forums.asp.net/user/Profile.aspx?UserID=73" target="_blank"&gt;Polita&lt;/a&gt; (who in addition to being the author of the &lt;b&gt;GridView&lt;/b&gt; control is also very generous with her expertise) clarified this for some of us. So here's what I learned.&lt;br /&gt;&lt;br /&gt;One possibility is that you are working with objects of some type, and you have a collection of them that you want to display in the &lt;b&gt;GridView&lt;/b&gt; control. Let's say you have Customer objects. You put a bunch of them into an &lt;b&gt;ArrayList&lt;/b&gt; (or, as noted, anything else that can enumerate). To bind the &lt;b&gt;GridView&lt;/b&gt; to this array, you set its &lt;b&gt;DataSource&lt;/b&gt; property to the array and, of course, call &lt;b&gt;DataBind&lt;/b&gt;. To display the data, you can create &lt;b&gt;BoundField&lt;/b&gt; objects (in code or declaratively), and you set their &lt;b&gt;DataField&lt;/b&gt; property to the name of the property that you want to display. Here's what the &lt;b&gt;GridView&lt;/b&gt; markup might look like:&lt;pre&gt;&amp;lt;asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false"&amp;gt;&lt;br /&gt;&amp;lt;Columns&amp;gt;&lt;br /&gt;   &amp;lt;asp:BoundField HeaderText="ID" DataField="CustId" /&amp;gt;&lt;br /&gt;   &amp;lt;asp:BoundField HeaderText="Name" DataField="Name" /&amp;gt;&lt;br /&gt;   &amp;lt;asp:BoundField HeaderText="City" DataField="City" /&amp;gt;&lt;br /&gt;&amp;lt;/Columns&amp;gt;&lt;br /&gt;&amp;lt;/asp:GridView&amp;gt;&lt;/pre&gt;And here's the code (slightly verbose, sorry) for a simple Customer type and for creating several of them, adding them to an &lt;b&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1419'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1419</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1419</guid><pubDate>Fri, 03 Feb 2006 01:03:48 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1419">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1419</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1419</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1419</wfw:commentRss><slash:comments>11</slash:comments></item><item><title>Custom bi-directional sorting in GridView</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1418</link><description>One of the things I like is how as you work with ASP.NET (or anything), your instincts develop a bit and you can figure out how to do stuff with only a few dents in your forehead where you've been banging it against the keyboard. &lt;br /&gt;&lt;br /&gt;I have an app that uses a &lt;b&gt;GridView&lt;/b&gt; control to display some information. The &lt;b&gt;GridView&lt;/b&gt; control includes sorting (for free), which is bidirectional (also for free). First you set &lt;b&gt;AllowSorting&lt;/b&gt;[&lt;A href='#custombidirectionalsortingingridview1'&gt;1&lt;/A&gt;] to true, them for each column (bound or templated), you set a sort expression. This renders a &lt;b&gt;LinkButton&lt;/b&gt; in the column header, and the grid toggles between sorting ascending and descending per your sort expression. Nice.&lt;br /&gt;&lt;br /&gt;For various reasons, in one of my apps I have to do the bi-directional part manually. But this isn't very hard at all. First, in the &lt;b&gt;GridView&lt;/b&gt; column, I specified a custom sort expression (that is, an expression that doesn't map directly to a database field):&lt;pre&gt;&amp;lt;asp:TemplateField HeaderText="Date" &lt;b&gt;SortExpression="datesort"&lt;/b&gt;&amp;gt;&lt;br /&gt;    &amp;lt;ItemTemplate&amp;gt;&lt;br /&gt;       &amp;lt;asp:Label ID="labelPDate" runat="server" Text=""&amp;gt;&amp;lt;/asp:Label&amp;gt;&lt;br /&gt;    &amp;lt;/ItemTemplate&amp;gt;&lt;br /&gt;&amp;lt;/asp:TemplateField&amp;gt;&lt;/pre&gt;In the page code, I created a DateSortDirection property, and I initialize it in the &lt;b&gt;Page_Load&lt;/b&gt; handler.&lt;pre&gt;Public Property DateSortDirection() As String&lt;br /&gt;   Get&lt;br /&gt;      Return ViewState("DateSortDirection")&lt;br /&gt;    End Get&lt;br /&gt;    Set(ByVal value As String)&lt;br /&gt;       ViewState("DateSortDirection") = value&lt;br /&gt;     End Set&lt;br /&gt;End Property&lt;br /&gt;&lt;p&gt;&lt;/p&gt;    &lt;br /&gt;Protected Sub Page_Load()&lt;br /&gt;   If Not Page.IsPostBack Then&lt;br /&gt;      Me.DateSortDirection = "ASC"&lt;br /&gt;   End If&lt;br /&gt;End Sub&lt;/pre&gt;To implement bidirectional sorting, I handle the grid's &lt;b&gt;Sorting&lt;/b&gt; handler:&lt;pre&gt;Protected Sub GridView1_Sorting(ByVal sender As Object, _&lt;br /&gt;        ByVal e As System.Web.UI.WebControls.GridViewSortEventArgs)&lt;br /&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1418'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1418</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1418</guid><pubDate>Wed, 01 Feb 2006 22:50:08 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1418">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1418</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1418</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1418</wfw:commentRss><slash:comments>14</slash:comments></item><item><title>Customizing the GridView Pager</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1405</link><description>I &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=1401" target="_blank"&gt;mentioned&lt;/a&gt; that I was using a &lt;b&gt;GridView&lt;/b&gt; control with paging, and I wanted to add a "Last" link to it that would always jump to the last page. This was one a them learning experiences.&lt;br&gt;&lt;br&gt;Years ago I attended an excellent user group presentation in which someone (forgot who, dang) showed some neat tricks for manipulating the links in a &lt;b&gt;DataGrid&lt;/b&gt; pager. That looked like fun, so in one of my apps I added code that would highlight the current page among the page links. Here's the code (idea lifted from someone smarter than me, I'll note again):&lt;pre&gt;Sub DataGrid1_ItemCreated(sender As Object, e As DataGridItemEventArgs)&lt;br&gt;   If e.Item.ItemType = ListItemType.Pager Then&lt;br&gt;      Dim i As Integer&lt;br&gt;      For i = 0 to e.Item.Cells(0).Controls.Count - 1&lt;br&gt;         If TypeOf( e.Item.Cells(0).Controls(i) ) Is Label Then&lt;br&gt;	   Dim l As Label = e.Item.Cells(0).Controls(i)&lt;br&gt;	   l.backcolor = System.Drawing.Color.violet&lt;br&gt;	   l.font.name = "Verdana"&lt;br&gt;	   l.font.bold = True&lt;br&gt;	   l.forecolor = System.Drawing.Color.White&lt;br&gt;	   l.text = " " &amp; l.text &amp; " "  ' Padding&lt;br&gt;         End If&lt;br&gt;      Next i&lt;br&gt;   End If&lt;br&gt;End Sub&lt;/pre&gt;When a grid row is created, the code first sees if this is the pager row. If so, it walks the controls in the pager cell. The current page will be displayed using a &lt;b&gt;Label&lt;/b&gt; control; other pages are displayed as &lt;b&gt;LinkButton&lt;/b&gt; controls. So when the code finds a &lt;b&gt;Label&lt;/b&gt; control, it tarts it all up with colors and stuff.&lt;br&gt;&lt;br&gt;The salient point here is this: in the &lt;b&gt;DataGrid&lt;/b&gt; contol, the pager row consists of a single cell with a colspan. Inside that single cell are the controls for paging. In the code, &lt;code&gt;e.Item.Cells(0)&lt;/code&gt; contains a collection of controls that are accessible at &lt;code&gt;ItemCreated&lt;/code&gt; time. I figured that the &lt;b&gt;GridView&lt;/b&gt; control would work the same. It doesn't, not quite. &lt;br&gt;&lt;br&gt;In the &lt;b&gt;GridView&lt;/b&gt; control, at &lt;code&gt;RowCreated&lt;/code&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1405'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1405</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1405</guid><pubDate>Fri, 13 Jan 2006 19:30:33 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1405">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1405</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1405</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1405</wfw:commentRss><slash:comments>4</slash:comments></item><item><title>Inserting into an XML file (and deleting)</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1401</link><description>Last time I &lt;a href="http://mikepope.com/blog/AddComment.aspx?blogid=1396" target="_blank"&gt;played around&lt;/a&gt; with updating an XML file using an &lt;b&gt;XmlDataSource&lt;/b&gt; control, a &lt;b&gt;GridView&lt;/b&gt; control, and a &lt;b&gt;DetailsView&lt;/b&gt; control. Inserting into an XML file is similar, in that guess what, you get to do all the work. One decision I made was to have a button on the page that would explictly put the &lt;b&gt;DetailsView&lt;/b&gt; control into insert mode. My use of the &lt;b&gt;DetailsView&lt;/b&gt; control is therefore maybe not exactly as it might have been designed:&lt;ul&gt;&lt;li&gt;Before any row in the &lt;b&gt;GridView&lt;/b&gt; control is selected, the &lt;b&gt;DetailsView&lt;/b&gt; control is invisible.&lt;br&gt;&lt;li&gt;When you select a row in the &lt;b&gt;GridView&lt;/b&gt; control, I make the &lt;b&gt;DetailsView&lt;/b&gt; control visible, but also put it into edit mode. When you update the selected row, I disappear the &lt;b&gt;DetailsView&lt;/b&gt; control again.&lt;br&gt;&lt;li&gt;To insert a new record, I click a button, which displays the &lt;b&gt;DetailsView&lt;/b&gt; control in insert mode. When I click Save, the &lt;b&gt;DetailsView&lt;/b&gt; control disappears again.&lt;/ul&gt;Make sense? IOW, I'm programmatically controlling the mode in which the &lt;b&gt;DetailsView&lt;/b&gt; control appears, rather than using any built-in functionality for that. And I'm really only displaying it in two modes, edit and insert.&lt;br&gt;&lt;br&gt;Here's the code to put the &lt;b&gt;DetailsView&lt;/b&gt; control into insert mode:&lt;pre&gt;Protected Sub buttonInsert_Click(ByVal sender As Object, _&lt;br&gt;        ByVal e As System.EventArgs)&lt;br&gt;    XmlDataSource2.Data = ""  ' Clear old data from control&lt;br&gt;    DetailsView1.DataBind()&lt;br&gt;    DetailsView1.Visible = True&lt;br&gt;    DetailsView1.ChangeMode(DetailsViewMode.Insert)&lt;br&gt;End Sub&lt;/pre&gt;If I don't set the &lt;b&gt;Data&lt;/b&gt; property (or do something like that), the &lt;b&gt;DetailsView&lt;/b&gt; control shows up with whatever record was last edited or inserted.&lt;br&gt;&lt;br&gt;When you click the Update button, here's what happens:&lt;pre&gt;Protected Sub DetailsView1_ItemInserting(ByVal sender As Object, _&lt;br&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1401'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1401</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1401</guid><pubDate>Sun, 08 Jan 2006 20:14:49 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1401">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1401</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1401</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1401</wfw:commentRss><slash:comments>9</slash:comments></item><item><title>Updating an XML file</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1396</link><description>As I &lt;a href="http://mikepope.com/blog/DisplayBlog.aspx?permalink=1375" target="_blank"&gt;blogged before&lt;/a&gt;, I've been playing with keeping my collection of quotations in an XML file. I noted then that I created the XML file by saving a dataset as XML, which made each column into an element. I used an &lt;b&gt;XmlDataSource&lt;/b&gt; control and a &lt;b&gt;DataList&lt;/b&gt; control to display the quotes on a page. But the &lt;b&gt;XmlDataSource&lt;/b&gt; control prefers to read attributes as columns, so I had to apply a transformation. Still, it worked.&lt;br&gt;&lt;br&gt;Bashing on, I'm interested in making the XML file updatable -- either by editing existing quotations (not that I ever make any typing mistakes, no) or by inserting a new quote. Everyone knows, I think, that the &lt;b&gt;XmlDataSource&lt;/b&gt; control is effectively read-only; it doesn't support any update methods, unlike, say, the &lt;b&gt;SqlDataSource&lt;/b&gt; control. So for sure my original goal, which was to see if I could this without coding, was not attainable. The question then became &lt;i&gt;how much&lt;/i&gt; code would be required to create an ASP.NET page that allowed me to edit and add quotations to the XML file.&lt;br&gt;&lt;br&gt;The first task was to set up editing. I figured that I'd use a &lt;b&gt;GridView&lt;/b&gt; control with paging to show the quotes and a &lt;b&gt;DetailsView&lt;/b&gt; control to edit or insert individual quotes -- in other words, a master-detail relationship. As it happens, there's a &lt;a href="http://msdn2.microsoft.com/en-us/library/13ftcwy9.aspx" target="_blank"&gt;walkthrough&lt;/a&gt; that illustrates this. &lt;br&gt;&lt;br&gt;The walkthrough uses two &lt;b&gt;XmlDataSource&lt;/b&gt; controls. The first (with transform) gets all the records for the &lt;b&gt;GridView&lt;/b&gt; control. The second (also with transform) gets a single record for the &lt;b&gt;DetailsView&lt;/b&gt; control, using an XPath expression (created dynamically) to find the record currently selected in the &lt;b&gt;GridView&lt;/b&gt; control.[&lt;A href='#updatinganmlfile1'&gt;1&lt;/A&gt;] My first problem was that the quotations don't have a unique ID, so I couldn't use a lookup like that illustrated in the walkthrough.&lt;br&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1396'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1396</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1396</guid><pubDate>Fri, 30 Dec 2005 00:59:13 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1396">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1396</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1396</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1396</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Choosing the Web server</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1387</link><description>Another question that has come up a few times. How can you control which Web server -- IIS or the ASP.NET Development Server (Cassini) -- is used to test pages in Visual Web Developer?&lt;br&gt;&lt;br&gt;For starters, the default behavior is that if you create a file system Web site, VWD will use Cassini. Specifically, when you run the Web site, VWD starts up Cassini on a non-default port (i.e., not port 80) and will then send to your default browser a request for the current or start page using http://localhost:&lt;i&gt;port&lt;/i&gt;/&lt;i&gt;page&lt;/i&gt;.aspx. The effect will be to cause Cassini to serve the page. (For info on how to set the port used by Cassini, see &lt;a href="http://msdn2.microsoft.com/en-us/library/ms178109.aspx" target="_blank"&gt;here&lt;/a&gt;.)&lt;br&gt;&lt;br&gt;For other Web site types, VWD uses different strategies. For a local IIS site, VWD launches the page with the URL http://localhost. For a remote IIS site, it uses the URL you specified when creating or opening the site. In both cases, this will effectively run the page using IIS.&lt;br&gt;&lt;br&gt;When you run an FTP site, you will sooner or later be asked to specify a base URL. This will be the HTTP URL that corresponds (per you or per your hosting site) to the FTP URL that you used to create or open the site. More or less by definition, this will also use IIS, since your hoster will be running IIS to support your ASP.NET site anyway. This is explained, with more detail, in the topic &lt;a href="http://msdn2.microsoft.com/en-us/library/bfx5as36.aspx" target="_blank"&gt;FTP-deployed Web Sites&lt;/a&gt;.&lt;br&gt;&lt;br&gt;Most of the questions I've seen around this have to do with creating a file system Web site but wanting to use IIS to test. As it happens, you can configure file system Web sites in much the same way you configure an FTP Web site. &lt;br&gt;&lt;br&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1387'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1387</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1387</guid><pubDate>Tue, 13 Dec 2005 09:12:13 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1387">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1387</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1387</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1387</wfw:commentRss><slash:comments>1</slash:comments></item><item><title>Disabled Insert, Update, Delete</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1385</link><description>Another question I've seen more than once. I believe that if this is documented, it's someplace that people don't stumble over readily. In Visual Web Developer, when you're running the Data Source Configuration wizard for the SqlDataSource or AccessDataSource controls, you can have the wizard generate Insert, Update, and Delete statements. To do this, in the wizard pane where you configure the Select statement, click the Advanced button to display the (duh) Advanced SQL Generation Options dialog box.&lt;br&gt;&lt;br&gt;&lt;img src="http://www.mikepope.com/blog/images/SQL_Advanced_Generation_Options.JPG"&gt;&lt;br&gt;&lt;br&gt;If the Generate checkbox isn't enabled, there's something in your Select query or database that makes it impossible to update. The most common situation by far is that the Select statement does not contain the primary key for the table in question. Another possibility is that you're working with a non-updatable view.&lt;br&gt;&lt;br&gt;A more subtle difference seems to be with the location of the database. One poster on the ASP.NET forums &lt;a href="http://forums.asp.net/1116878/ShowPost.aspx" target="_blank"&gt;reports&lt;/a&gt; that when working with SQL Server Express, they experienced this problem because the .mdf file was not in the App_Data folder. This suggests a permissions problem, but I haven't investigated further.&lt;br&gt;&lt;br&gt;Anyway, the short answer, which might be a little too generic, is that the option to generate update statements requires that the query and database have sufficient information (and permissions) to support update.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1385</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1385</guid><pubDate>Fri, 09 Dec 2005 08:51:05 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1385">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1385</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1385</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1385</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Solution file location</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1381</link><description>My working rule here is that if I see the same question multiple times, I (or someone) should probably blog it. Today: in Visual Studio 2005, how do you control where project and solution information is stored?&lt;br&gt;&lt;br&gt;The short answer I learned from &lt;a href="http://go.microsoft.com/fwlink/?LinkId=55638" target="_blank"&gt;a whitepaper on MSDN&lt;/a&gt;:&lt;blockquote&gt;When creating a new Web site project that you will add other projects to (such as a class library project or a Web Deployment project), start by creating an empty solution in the location of your choice. Then add the new Web site to that solution. This ensures that Visual Studio puts all of the project files in the same set of directories and subdirectories.&lt;/blockquote&gt;The author there is &lt;a href="http://weblogs.asp.net/bradleyb/" target="_blank"&gt;BradleyB&lt;/a&gt;, who's the Dev lead on project stuff for Visual Web Developer. Check out his blog (linked) for other great tips on using the IDE in VWD. For example, yesterday he posted a bunch of tips for how to optimize builds in the IDE.&lt;br&gt;&lt;br&gt;Note that this won't be possible in Express Edition, since you cannot create a multi-project solution in that product.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1381</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1381</guid><pubDate>Wed, 07 Dec 2005 12:42:01 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1381">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1381</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1381</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1381</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>Dynamic+static title</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1376</link><description>In the blog, I read the blog title from application settings in the Web.config file, and then I tack onto that title the current page title. I have traditionally done this by using a data-binding expression and calling a public method to return the string I wanted, like this:&lt;br&gt;&lt;div style="margin-left:25px"&gt;&lt;pre&gt;&amp;lt;title id="blogTitle"&amp;gt;&amp;lt;% =GetPageTitle()%&amp;gt; /about&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;/div&gt;with a method like this:&lt;div style="margin-left:25px"&gt;&lt;pre&gt;Public Function GetPageTitle()&lt;br&gt;   Return ConfigurationSettings.AppSettings("blogTitle")&lt;br&gt;End Function&lt;/pre&gt;&lt;/div&gt;In 2.0, we introduced an expanded set of inline expressions. One of the is the AppSettings expression, which will read an application setting out of the config file and substitute it. As an experiment, I tried all kinds of variations on this to mix the dynamic part with the static "/about" (or similar) that I add on for each page:&lt;br&gt;&lt;div style="margin-left:25px"&gt;&lt;pre&gt;&amp;lt;title runat="server" title="&amp;lt;%$ AppSettings:blogtitle %&gt; /about "/&gt; &amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;/div&gt;IOW, I tried using an expression directly into a &amp;lt;title&amp;gt; tag to which I'd added runat="server". It didn't work, however. In the end, I had to do use &lt;i&gt;two&lt;/i&gt; ASP.NET Literal controls, one for the expression and a separate one for the static text. Like this:&lt;div style="margin-left:25px"&gt;&lt;pre&gt;&amp;lt;title runat="server" &amp;gt;&lt;br&gt;   &amp;lt;asp:literal runat="server" text="&amp;lt;%$ AppSettings:blogtitle %&amp;gt;" /&amp;gt;&lt;br&gt;   &amp;lt;asp:literal runat="server" text="/about" /&gt; &lt;br&gt;&amp;lt;/title&amp;gt;&lt;/pre&gt;&lt;/div&gt;I was hoping there might be a way to specify a formatting string with the AppSetting: expression. If so, I haven't found it yet.&lt;br&gt;&lt;br&gt;PS Of course, you can set the title dynamically with code like this:&lt;pre&gt;Page.Header.Title = ConfigurationManager.AppSettings("blogTitle") &amp; "/about"&lt;/pre&gt;(Note new class for getting configuration settings.) But I wanted to do it all declaratively.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey,writing</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1376</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1376</guid><pubDate>Thu, 01 Dec 2005 00:51:08 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1376">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1376</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1376</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1376</wfw:commentRss><slash:comments>2</slash:comments></item><item><title>Elements and transformations</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1375</link><description>Since I have this-here newfangled ASP.NET 2.0 to play with, I thought I'd do something, you know, simple, just for fun. I have a list of quotations that I keep for the blog (over there on the left). At the moment, I maintain those as a text file (!); to display them, I use a stream reader to slurp them out of the text file into rows in a dataset. The show-all-quotations page uses a Repeater.&lt;br&gt;&lt;br&gt;This seemed like an interesting thing to do XML-ishly. It's not that the old system had any particular flaws, but I thought I might be able to cut down on the coding by using an XmlDataSource control to read the quotations -- voil&amp;agrave;, direct data binding! Right? Also perhaps to write out new quotes when I found them.&lt;br&gt;&lt;br&gt;I read the quotes into a dataset and then used DataSet.WriteXml to create an XML file. The format looks like this:&lt;pre&gt;&amp;lt;?xml version="1.0" standalone="yes"?&amp;gt;&lt;br&gt;&amp;lt;Quotations&amp;gt;&lt;br&gt;  &amp;lt;Quotation&amp;gt;&lt;br&gt;    &amp;lt;quote&amp;gt;A man may write at any time, if he will set himself doggedly to it.&amp;lt;/quote&amp;gt;&lt;br&gt;    &amp;lt;author&amp;gt;Samuel Johnson&amp;lt;/author&amp;gt;&lt;br&gt;    &amp;lt;source /&amp;gt;&lt;br&gt;  &amp;lt;/Quotation&amp;gt;&lt;br&gt;  &amp;lt;Quotation&amp;gt;&lt;br&gt;    &amp;lt;quote&amp;gt;I have made this letter longer than usual, only because I have not had the &lt;br&gt;          time to make it shorter.&amp;lt;/quote&amp;gt;&lt;br&gt;    &amp;lt;author&amp;gt;Blaise Pascal&amp;lt;/author&amp;gt;&lt;br&gt;    &amp;lt;source /&amp;gt;&lt;br&gt;  &amp;lt;/Quotation&amp;gt;&lt;br&gt;  &amp;lt;Quotation&amp;gt;&lt;br&gt;    &amp;lt;quote&amp;gt;Knowledge is of two kinds. We know a subject ourselves, or we know we can &lt;br&gt;          find information upon it.&amp;lt;/quote&amp;gt;&lt;br&gt;    &amp;lt;author&amp;gt;Samuel Johnson&amp;lt;/author&amp;gt;&lt;br&gt;    &amp;lt;source /&amp;gt;&lt;br&gt;  &amp;lt;/Quotation&amp;gt;&lt;br&gt;&amp;lt;/Quotations&amp;gt;&lt;/pre&gt;where &amp;lt;source&amp;gt; is for a URL, if any.&lt;br&gt;&lt;br&gt;I created a new page and added an XmlDataSource control and a DataList control. And I could &lt;i&gt;not&lt;/i&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1375'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1375</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1375</guid><pubDate>Wed, 30 Nov 2005 21:56:14 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1375">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1375</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1375</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1375</wfw:commentRss><slash:comments>3</slash:comments></item><item><title>ASP.NET dev server and port numbers</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1371</link><description>Another tip. This is documented, but a lot of people have asked, so it must not be very discoverable. The question is: In Visual Web Developer, when using the ASP.NET Development Server (very unofficially known as Cassini), can you set the port number that it uses?&lt;br&gt;&lt;br&gt;By default, the server randomly picks an open port, and it uses a different port each time. I forget why we went to a dynamic port model rather than just enabling people to specify a port, but I do remember that the fixed port number used by Cassini in Web Matrix (port 8080) occasionally was a problem for people. In any event, in VWD people sometimes do want to use a fixed port number. Referencing a Web service, for example, is a lot easier if you know what port will be included in the URL.&lt;br&gt;&lt;br&gt;It's easy to change the behavior. In Solution Explorer, select the name of the project. Then in the Properties window, you can set &lt;b&gt;Use dynamic ports&lt;/b&gt; to false, and set &lt;b&gt;Port number&lt;/b&gt; to the port you want to use.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1371</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1371</guid><pubDate>Mon, 28 Nov 2005 11:22:14 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1371">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1371</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1371</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1371</wfw:commentRss><slash:comments>0</slash:comments></item><item><title>ObjectDataSource: pros and cons</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1370</link><description>Someone internally asked about the benefits and disadvantages of using the ObjectDataSource control. Eilon Lipton from our team responded with the following:&lt;blockquote&gt;As the author of the ObjectDataSource, I might be a bit biased, but here's a start:&lt;br&gt; &lt;br&gt;&lt;b&gt;Pros&lt;/b&gt;&lt;ul&gt;&lt;li&gt;Automatic two-way databinding with data bound controls such as the GridView and FormView&lt;br&gt;&lt;li&gt;Automatic binding of method parameters to other pieces of data (ControlParameter, QueryStringParameter, etc.) for Select/Insert/Update/Delete&lt;br&gt;&lt;li&gt;Better separation of UI and code&lt;br&gt;&lt;li&gt;Hooks up easily to VS Data Components&lt;br&gt;&lt;li&gt;Better design time support in data bound controls. For example, you object's schema appears in the GridView's "Edit Columns" dialog.&lt;/ul&gt; &lt;br&gt;&lt;b&gt;Cons&lt;/b&gt;&lt;ul&gt;&lt;li&gt;Slight performance hit. I don't recall what our measurements were, but the hit was definitely under 10% for a Select method that returned static data. Keep in mind that with a "real" data object, the Select method would go to a database or somewhere else fairly slow (as compared to returning static data). As such, the hit in a real scenario is probably quite a bit less.&lt;br&gt;&lt;li&gt;Requires specific patterns for writing business objects. It's fairly flexible, but some scenarios are tricky to work with.&lt;/ul&gt;&lt;/blockquote&gt;There you go -- straight from the, uh, author's mouth.</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1370</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1370</guid><pubDate>Mon, 28 Nov 2005 10:40:05 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1370">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1370</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1370</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1370</wfw:commentRss><slash:comments>1</slash:comments></item><item><title>Grid and Flow modes in Visual Web Developer</title><link>http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1367</link><description>I've seen this question a couple of times on the forums: what happened to Grid mode (and Flow mode) in the Visual Studio Web page designer? In VS2003, the default was Grid mode, with the option to switch to Flow mode.[&lt;A href='#gridandflowmodeinvisualwebdeveloper1'&gt;1&lt;/A&gt;] In reality, of course, Grid view is absolute (css) positioning, and flow mode is, uh, no positioning. (I'd say it's "normal" HTML, but I don't think we can say that non-CSS positioning of HTML elements is necessarily the norm these days.)&lt;br&gt;&lt;br&gt;Anyway, you can still get the effect of Grid mode, no problem. To be able to x/y position a single control, select it in Design view and then choose &lt;b&gt;Layout&lt;/b&gt; &amp;gt; &lt;b&gt;Position&lt;/b&gt; &amp;gt; &lt;b&gt;Absolute&lt;/b&gt;. Drag and enjoy. You can multi-select if you are so inclined.&lt;br&gt;&lt;br&gt;To emulate a perma-Grid-mode, choose &lt;b&gt;Layout&lt;/b&gt; &amp;gt; &lt;b&gt;Position&lt;/b&gt; &amp;gt; &lt;b&gt;Auto-position Options&lt;/b&gt;. There you will find a checkbox with a caption way too long to type out, so I'll just show you a picture:&lt;br&gt;&lt;br&gt;&lt;img src="http://www.mikepope.com/blog/images/vwd_positioning_db.JPG"&gt;&lt;br&gt;&lt;br&gt;Check the box and select the positioning option you need. Note that &lt;a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/position.asp" target="_blank"&gt;static&lt;/a&gt; is a positioning option that has exactly the same effect as Not Set, which means no attribute set at all.&lt;br&gt;&lt;br&gt;Selecting this option doesn't turn the whole design surface into using Grid mode -- it just adds x/y coordinates to any new controls you add via the common UI gestures. Controls that aren't already configured for x/y positioning will still be static.&lt;br&gt;&lt;br&gt;There is actually a reason for this change. An overarching philosophy for the Web page editor in this release was "no designer goo in the page." (To, um, paraphrase slightly.) In VS2003, as you'll remember, we implemented Grid mode by adding non-standard attributes to the &amp;lt;body&amp;gt; tag:&lt;br&gt;&lt;br&gt;&lt;code&gt;&amp;lt;body MS_POSITIONING="GridLayout"&amp;gt;&lt;/code&gt;&lt;br&gt;&lt;br&gt; [&lt;a href='http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1367'&gt;more&lt;/a&gt;]</description><author>Mike Pope&lt;mike@mikepope.com&gt;</author><category>aspnet,whidbey</category><wfw:comment>http://www.mikepope.com/blog/AddComment.aspx?blogID=1367</wfw:comment><guid isPermaLink="true">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1367</guid><pubDate>Mon, 21 Nov 2005 23:47:19 GMT</pubDate><source url="http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1367">http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1367</source><trackback:ping>http://www.mikepope.com/blog/BlogTrackback.aspx?id=1367</trackback:ping><wfw:commentRss>http://www.mikepope.com/blog/BlogCommentsFeed.rss?id=1367</wfw:commentRss><slash:comments>1</slash:comments></item></channel></rss>