<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://scottonwriting.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Scott On Writing.NET : ASP.NET Talk, Blog Enhancements</title><link>http://scottonwriting.net/sowblog/archive/tags/ASP.NET+Talk/Blog+Enhancements/default.aspx</link><description>Tags: ASP.NET Talk, Blog Enhancements</description><dc:language>en</dc:language><generator>CommunityServer 2007 (Build: 20423.869)</generator><item><title>Search Your Site Using Google's Custom Search Engine</title><link>http://scottonwriting.net/sowblog/archive/2008/09/15/163311.aspx</link><pubDate>Mon, 15 Sep 2008 12:51:00 GMT</pubDate><guid isPermaLink="false">2814ed8b-42a8-4dfe-b0b1-a7acb3e6d762:163311</guid><dc:creator>Scott Mitchell</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://scottonwriting.net/sowblog/rsscomments.aspx?PostID=163311</wfw:commentRss><comments>http://scottonwriting.net/sowblog/archive/2008/09/15/163311.aspx#comments</comments><description>&lt;p&gt;Remember when people used to debate what search engine was the best among the bunnch? Do you remember back in the day when Yahoo! differentiated itself from other search engines by having actual human beings catalog, summarize, and rate large swaths of the World Wide Web? Today, search is a commodity. It's ubiquitous. Web surfers expect there to be a search box and expect accurate results returned in the blink of an eye. Because of these expectations, it's now more important than ever that your website offers search. I don't care if the site has only five static web pages that only get updated once in a blue moon, you still need search. &lt;/p&gt;
&lt;p&gt;The good news is that Google offers free tools for quickly and easily adding search to your site. With Google's &lt;a href="http://www.google.com/coop/cse/"&gt;Custom Search Engine (CSE)&lt;/a&gt; you can add search to your site within a matter of minutes. All it takes is configuring a few settings and then copying and pasting a snippet or two of HTML and JavaScript into your site. A couple of months ago I used CSE to add search to this blog. You can find the search interface in the upper right hand corner of every page or by visiting the &lt;a href="http://scottonwriting.net/sowBlog/SearchResults.htm"&gt;Search page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To learn how to add a search engine to your site using CSE check out my latest article on &lt;a href="http://dotnetslackers.com/"&gt;DotNetSlackers&lt;/a&gt;: &lt;em&gt;&lt;a href="http://dotnetslackers.com/articles/aspnet/Implementing-Search-in-ASP-NET-with-Google-Custom-Search.aspx"&gt;Implementing Search in ASP.NET with Google Custom Search&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Site Note: &lt;/strong&gt;Another technique for making your site more searchable is to create an &lt;a href="http://www.opensearch.org/"&gt;OpenSearch provider&lt;/a&gt;. By adding a simple XML file to your website you can have your site searchable through the search box that's baked into the user interface of browsers like Internet Explorer and Firefox. Learn more about this technique by reading: &lt;em&gt;&lt;a href="http://aspnet.4guysfromrolla.com/articles/073008-1.aspx"&gt;Helping Visitors Search Your Site By Creating an OpenSearch Provider&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://scottonwriting.net/aggbug.aspx?PostID=163311" width="1" height="1"&gt;</description><category domain="http://scottonwriting.net/sowblog/archive/tags/ASP.NET+Talk/default.aspx">ASP.NET Talk</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Blog+Enhancements/default.aspx">Blog Enhancements</category></item><item><title>FeedBurner and Changing a Blog's Feed URL</title><link>http://scottonwriting.net/sowblog/archive/2005/08/28/163103.aspx</link><pubDate>Sun, 28 Aug 2005 21:23:00 GMT</pubDate><guid isPermaLink="false">2814ed8b-42a8-4dfe-b0b1-a7acb3e6d762:163103</guid><dc:creator>Scott Mitchell</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://scottonwriting.net/sowblog/rsscomments.aspx?PostID=163103</wfw:commentRss><comments>http://scottonwriting.net/sowblog/archive/2005/08/28/163103.aspx#comments</comments><description>&lt;p&gt;This weekend I moved over my RSS feed - previously &lt;a href="http://scottonwriting.net/sowBlog/Rss.aspx"&gt;http://ScottOnWriting.NET/sowBlog/Rss.aspx&lt;/a&gt; - to a feed managed by &lt;a href="http://www.feedburner.com/"&gt;FeedBurner&lt;/a&gt; (&lt;a href="http://feeds.feedburner.com/ScottOnWriting"&gt;http://feeds.feedburner.com/ScottOnWriting&lt;/a&gt;).  FeedBurner serves as a sort of feed URL proxy.  Basically you give FeedBurner a link to your RSS feed and it creates a feed based on that feed.  You then point your subscribers to the FeedBurner feed and FeedBurner serves up your site's content, maintains statistics on who's subscribing to your blog, and so on.&lt;/p&gt;
&lt;p&gt;I decided to move to FeedBurner to realize three benefits (keep in mind that ScottOnWriting.NET (still) runs off of an old version of &lt;a href="http://scottwater.com/blog"&gt;Scott Watermasysk&lt;/a&gt;'s &lt;a href="http://workspaces.gotdotnet.com/dottext"&gt;.Text blogging engine&lt;/a&gt;, as I've yet to upgrade to &lt;a href="http://communityserver.org/"&gt;Community Server&lt;/a&gt;; previous to today, I was actually using a pre-0.94 version, but today "upgraded" to the official 0.94 release downloadable from the .Text GotDotNet Workspace):&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Subscription statistics&lt;/strong&gt; - FeedBurner provides a number of free statistics, including number of subscribers, number of requests, and aggregator breakdown. 
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Someone else handles the bandwidth&lt;/strong&gt; - currently requests to the RSS feed on ScottOnWriting.NET consume roughly 1.5 GB of traffic per week, or 6 GB of traffic per month (in total, ScottOnWriting does about 11 GB of traffic per month).  That's a lot of 1s and 0s that would be nice to offload to another party.  (I don't believe the pre-0.94 version of .Text I was using supported &lt;a href="http://fishbowl.pastiche.org/2002/10/21/http_conditional_get_for_rss_hackers"&gt;conditional HTTP GETs&lt;/a&gt; (although if I'm not mistaken the "official" 0.94 release does; had I been using a version that supported conditional GETs this bandwidth requirement would be an order of magnitude lower, I'd wager, perhaps just a GB for the month.)  (&lt;em&gt;To clarify, while FeedBurner does make requests to the blog's RSS URL, it caches the results for a period of time, thereby reducing the bandwidth demands for my server.&lt;/em&gt;)
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;FeedBurner has a couple of neat “publicizing“ tools&lt;/strong&gt; - FeedBurner includes a number of tools to easily make links to add your blog to My Yahoo!, MyMSN, newgator Online, and so on.  Additionally, there are nifty little tools you can use to “show off“ how many folks subscribe to your blog, a la: &lt;img style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height="26" alt="" src="http://feeds.feedburner.com/~fc/ScottOnWriting?bg=99CCFF&amp;amp;fg=444444&amp;amp;anim=0" width="88" /&gt;&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;When changing over your RSS feed URL the main challenge is making sure that your existing subscriber base starts to use the new feed URL.  There are, to my knowledge, to ways this can be done, with the first of the two ways being the ideal way:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Have your old feed URL emit an HTTP 301 status code&lt;/strong&gt; - The &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"&gt;HTTP 301 status code&lt;/a&gt; is a message from the server to the client saying, “Hey, this resource has been permanently moved to URL &lt;em&gt;xyz&lt;/em&gt;.“  The client, then, can make a new request to the specified URL; too, if there's some database being used to track the URL, this message informs the client that it's time to update the database and use the new location.  If I'm not mistaken, virtually all modern aggregators support HTTP 301 status codes and will automatically update a site's feed URL to use the newly specified location. 
&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Tell people of your new feed URL&lt;/strong&gt; - if you do not have control over your blog website you may not be able to take the steps needed to replace the current feed URL with an HTTP 301 status code.  In this case, the only approach I know of to inform users of the new feed URL is simply through word of mouth.  That is, you'll just have to post on your blog an entry telling users to update their aggregators.  As &lt;a href="http://www.acmebinary.com/blogs/kent/"&gt;Kent Sharkey&lt;/a&gt; has noted, though, &lt;a href="http://www.acmebinary.com/blogs/kent/archive/2005/08/22/212.aspx"&gt;the results may be somewhat disappointing&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Since I run ScottOnWriting.NET myself (well, through a web hosting company), I have control over these matters.  The only challenge, then, was getting .Text to play nice.  In .Text version 0.94 the site's RSS feed comes from a file named &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;.  This file, though, does not actually exist; rather, in the &lt;font face="Courier New"&gt;Web.config&lt;/font&gt; file all requests are handed off to a .Text &lt;a href="http://msdn.microsoft.com/asp.net/default.aspx?pull=/library/en-us/dnaspp/html/httphandl.asp"&gt;HTTP Handler&lt;/a&gt;.  When a request comes in for &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;, .Text generates the appropriate output.&lt;/p&gt;
&lt;p&gt;To get Rss.aspx replaced with an HTTP 301 status code, the first step is to create an &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt; file in your blog's root directory.  The code needed for this page is alarmingly simple - all you want to do is return an HTTP 301 specifying the new feed URL, like so:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;script&lt;/font&gt; &lt;font color="#ff0000"&gt;runat&lt;/font&gt;&lt;font color="#0000ff"&gt;="server"&lt;/font&gt; &lt;font color="#ff0000"&gt;language&lt;/font&gt;&lt;font color="#0000ff"&gt;="C#"&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;br /&gt;&lt;font color="#0000ff"&gt;void&lt;/font&gt; Page_Load(&lt;font color="#0000ff"&gt;object&lt;/font&gt; sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;    Response.Status = &lt;font color="#800080"&gt;"301 Moved Permanently"&lt;/font&gt;;&lt;br /&gt;    Response.AddHeader(&lt;font color="#800080"&gt;"Location"&lt;/font&gt;, &lt;font color="#800080"&gt;"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color="#800080"&gt;http://feeds.feedburner.com/ScottOnWriting&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#800080"&gt;"&lt;/font&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;font color="#0000ff"&gt;&amp;lt;/&lt;/font&gt;&lt;font color="#a52a2a"&gt;script&lt;/font&gt;&lt;font color="#0000ff"&gt;&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;(Of course replace the &lt;a href="http://feeds.feedburner.com/ScottOnWriting"&gt;http://feeds.feedburner.com/ScottOnWriting&lt;/a&gt; Location header value with the URL of &lt;em&gt;your&lt;/em&gt; new RSS feed...)&lt;/p&gt;
&lt;p&gt;Creating this file is not enough.  In fact, even after creating this file if you visit &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt; through your browser you'll &lt;em&gt;still&lt;/em&gt; see the complete RSS feed rather than being auto-redirected to the specified URL.  This is because the ASP.NET engine is handing off the request to the .Text HTTP Handler rather than handling the request itself.  If you look at the &lt;font face="Courier New"&gt;&amp;lt;httpHandlers&amp;gt;&lt;/font&gt; section in the &lt;font face="Courier New"&gt;Web.config&lt;/font&gt; file you'll find an entry like:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;add&lt;/font&gt; &lt;font color="#ff0000"&gt;verb&lt;/font&gt;&lt;font color="#0000ff"&gt;="*" &lt;/font&gt;&lt;font color="#ff0000"&gt;path&lt;/font&gt;&lt;font color="#0000ff"&gt;="*.aspx"&lt;/font&gt; &lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;font color="#0000ff"&gt;="Dottext.Framework.UrlManager.UrlReWriteHandlerFactory,Dottext.Framework" /&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;This entry says, “Any request for an ASP.NET page should be handled by the class &lt;font face="Courier New"&gt;Dottext.Framework.UrlManager.UrlReWriteHandlerFactory,Dottext.Framework&lt;/font&gt;,” and HTTP Handler. This includes requests for &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;.  Hence we need to add the following line to the &lt;font face="Courier New"&gt;&amp;lt;httpHandlers&amp;gt;&lt;/font&gt; section:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;add &lt;/font&gt;&lt;font color="#ff0000"&gt;verb&lt;/font&gt;&lt;font color="#0000ff"&gt;="*"&lt;/font&gt; &lt;font color="#a52a2a"&gt;path&lt;/font&gt;&lt;font color="#0000ff"&gt;="Rss.aspx" &lt;/font&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;font color="#0000ff"&gt;="System.Web.UI.PageHandlerFactory" /&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;That tells the ASP.NET engine to take care of requests to &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;.  At first I naively thought that I was done, but I had just unwittingly setup an infinite loop!  When a request comes into &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;, it sends back a 301 status code to the client, saying, “No, no, no, you want to go to this FeedBurner URL.“  This is what we want to tell people coming through a browser or aggregator, but remember that FeedBurner &lt;em&gt;also&lt;/em&gt; needs to know the URL of the site's feed, which, at this point, I had set simply as &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;!  So when FeedBurner periodically checked to see if a new version of my feed was available it requested &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;, which told it to check itself, which says to check &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;, which says to check itself, which... you get the point.&lt;/p&gt;
&lt;p&gt;Instead, what I needed to do was &lt;em&gt;rename&lt;/em&gt; .Text's &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt; to something else, like &lt;font face="Courier New"&gt;RssFromText.aspx &lt;/font&gt;and instruct FeedBurner to use this alternate, “secretive” feed URL.  With this setup, a user who already subscribes to ScottOnWriting.NET through &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt; will automatically be switched over to FeedBurner.  FeedBurner's RSS content will be populated from &lt;font face="Courier New"&gt;RssFromText.aspx&lt;/font&gt;, which will be generated from .Text, reflecting the most recent blog entries.  No more infinite loops!&lt;/p&gt;
&lt;p&gt;To accomplish this I had to edit blog.config to tell .Text that it should use &lt;font face="Courier New"&gt;RssFromText.aspx&lt;/font&gt; as its RSS feed URL as opposed to &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;.  This involved updating the appropriate &lt;font face="Courier New"&gt;&amp;lt;HttpHandler&amp;gt;&lt;/font&gt; line like so:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;HttpHandler &lt;/font&gt;&lt;font color="#ff0000"&gt;Pattern &lt;/font&gt;&lt;font color="#0000ff"&gt;= "(?:\/&lt;strong&gt;RssFromText.aspx&lt;/strong&gt;)$"&lt;/font&gt; &lt;font color="#ff0000"&gt;Type &lt;/font&gt;&lt;font color="#0000ff"&gt;= "Dottext.Framework.Syndication.RssHandler, Dottext.Framework"&lt;/font&gt; &lt;font color="#ff0000"&gt;HandlerType&lt;/font&gt; &lt;font color="#0000ff"&gt;= "Direct" /&amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;With this addition, requests now to &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt; are sent back an HTTP 301 status code, but FeedBurner can still slurp down the site's content through &lt;font face="Courier New"&gt;RssFromText.aspx&lt;/font&gt;.&lt;/p&gt;
&lt;p&gt;Next, you'll probably want to update the link to the site's feed in the &lt;strong&gt;My Links&lt;/strong&gt; section (since this will point the users to &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;, but you want them to go directly to the FeedBurner link).  (In actuality, this step is probably optional since even if you do leave it as Rss.aspx, when the attempt to view that page through a browser or slurp it through an aggregator, they'll get the 301 status code and auto-redirect to the FeedBurner URL... but still, for completeness let's change this link.)  To accomplish this, simply edit the &lt;font face="Courier New"&gt;MyLinks.ascx&lt;/font&gt; file in the &lt;font face="Courier New"&gt;~/Skins/&lt;em&gt;skin_name&lt;/em&gt;/Controls/&lt;/font&gt; directory.  With version 0.94 you'll find two HyperLink controls that .Text automatically looks for and sets their &lt;font face="Courier New"&gt;NavigateUrl&lt;/font&gt; properties to &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt; - these controls have &lt;font face="Courier New"&gt;ID&lt;/font&gt;s &lt;font face="Courier New"&gt;Syndication&lt;/font&gt; and &lt;font face="Courier New"&gt;XMLLink&lt;/font&gt;.  Even if you explicitly set the &lt;font face="Courier New"&gt;NavigateUrl&lt;/font&gt; properties to your FeedBurner URL, .Text will overwrite it and the link will be rendered as &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;.  If you try to simply remove these HyperLink controls you'll find that (at least with 0.94) .Text will barf.  What I did was simply set their &lt;font face="Courier New"&gt;Visible&lt;/font&gt; property to False.  I then added two HyperLink Web controls of my own that referenced the new feed URL.&lt;/p&gt;
&lt;p&gt;There's one more facet that should be changed, although I've not made the change since (to my understanding) you'd need to actually hack the .Text source code, recompile, and re-deploy.  In the &lt;font face="Courier New"&gt;&lt;/font&gt;portion of the web pages in your blog you'll find a &lt;font face="Courier New"&gt;&lt;link /&gt;&lt;/font&gt;tag that's used for RSS feed auto-discovery:&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;&lt;/font&gt;&lt;font color="#a52a2a"&gt;link &lt;/font&gt;&lt;font color="#ff0000"&gt;rel&lt;/font&gt;&lt;font color="#0000ff"&gt;="alternate"&lt;/font&gt; &lt;font color="#ff0000"&gt;href&lt;/font&gt;&lt;font color="#0000ff"&gt;="&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" color="#0000ff"&gt;http://scottonwriting.net/sowblog/rss.aspx&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;" &lt;/font&gt;&lt;font color="#ff0000"&gt;type&lt;/font&gt;&lt;font color="#0000ff"&gt;="application/rss+xml"&lt;/font&gt; &lt;font color="#ff0000"&gt;title&lt;/font&gt;&lt;font color="#0000ff"&gt;="RSS" &amp;gt;&lt;/font&gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Ideally the href attribute would contain the URL of your new feed... but I didn't feel like going through the headache of pecking through the source, making a change, testing, and so forth.  So I just left it as-is, figuring in the worst case someone will “discover” my feed to be &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;, which will automatically be updated to the FeedBurner syndication URL as soon as their aggregator makes its first request to &lt;font face="Courier New"&gt;Rss.aspx&lt;/font&gt;.&lt;/p&gt;
&lt;p&gt;The FeedBurner service looks pretty cool upon first glance.  Once this new feed URL gets some use and I get some metrics in FeedBurner's database, I plan on sharing some of the stats... it'll be interesting to see what the most popular aggregator out there is for those who are ASP.NET developers (the primary audience of this blog, I imagine), among other data points.&lt;/p&gt;&lt;img src="http://scottonwriting.net/aggbug.aspx?PostID=163103" width="1" height="1"&gt;</description><category domain="http://scottonwriting.net/sowblog/archive/tags/ASP.NET+Talk/default.aspx">ASP.NET Talk</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Miscellaneous/default.aspx">Miscellaneous</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Blog+Enhancements/default.aspx">Blog Enhancements</category></item><item><title>Searching Your Blog Got a Whole Lot Easier</title><link>http://scottonwriting.net/sowblog/archive/2005/02/01/163043.aspx</link><pubDate>Tue, 01 Feb 2005 14:54:00 GMT</pubDate><guid isPermaLink="false">2814ed8b-42a8-4dfe-b0b1-a7acb3e6d762:163043</guid><dc:creator>Scott Mitchell</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://scottonwriting.net/sowblog/rsscomments.aspx?PostID=163043</wfw:commentRss><comments>http://scottonwriting.net/sowblog/archive/2005/02/01/163043.aspx#comments</comments><description>&lt;p&gt;If you check out the &lt;a href="http://scottonwriting.net/sowblog/"&gt;ScottOnWriting.NET homepage&lt;/a&gt; you'll now find that in the upper-left hand corner there's a spiffy “Search” box.  Go ahead, type a query in there... you'll be redirected to &lt;a href="http://scottonwriting.net/Search.aspx?s=ScottOnWriting.NET&amp;amp;count=10&amp;amp;first=1&amp;amp;query=query"&gt;http://scottonwriting.net/Search.aspx?s=ScottOnWriting.NET&amp;amp;count=10&amp;amp;first=1&amp;amp;query=&lt;em&gt;query&lt;/em&gt;&lt;/a&gt;, which will show you the results of your search.&lt;/p&gt;
&lt;p&gt;The new search page - which you, too, can add to your site in a matter of minutes - is possible in large part thanks to Microsoft's new &lt;a href="http://search.msn.com/"&gt;MSN Search&lt;/a&gt;.  Today Microsoft unveiled their new “built from the ground up” search and one of the cool features it that the search results can be returned as RSS.  (To try it out, go to the MSN Search page and enter a query; at the bottom of the Web page you'll find that little, friendly orange RSS button.)  Once I found this, I realized adding search to ScottOnWriting.NET would be a cinch &lt;em&gt;if&lt;/em&gt; MSN Search let me search for pages on a particular domain.  Thankfully, you can search by a specific site by simply adding &lt;font face="Courier New"&gt;site:&lt;em&gt;siteName&lt;/em&gt;&lt;/font&gt; syntax in the search query.&lt;/p&gt;
&lt;p&gt;Creating a search engine for a local site, then, is as easy as having a page that requests the remote RSS file based on the query entered by a user, and displaying the resulting RSS in the page.  With my free &lt;a href="http://scottonwriting.net/sowBlog/RssFeed.htm"&gt;RssFeed&lt;/a&gt; control doing exactly this is a no-brainer, requiring just two lines of code.  Therefore, the code and markup for the search page for ScottOnWriting.NET basically looks like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source Code&lt;/strong&gt;&lt;br /&gt;&lt;font face="Courier New"&gt;// Build up the request URL for the RSS data&lt;br /&gt;string requestUrl = string.Format("&lt;/font&gt;&lt;a href="http://beta.search.msn.com/results.aspx?q={0}+site%3a{1}&amp;amp;format=rss&amp;amp;first={2}&amp;amp;count={3"&gt;&lt;font face="Courier New"&gt;http://beta.search.msn.com/results.aspx?q={0}+site%3a{1}&amp;amp;format=rss&amp;amp;first={2}&amp;amp;count={3&lt;/font&gt;&lt;/a&gt;&lt;font face="Courier New"&gt;}", searchQuery, “http://ScottOnWriting.NET/“, startIndex, resultsPerPage);&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;// Bind the results to the RssFeed control&lt;br /&gt;searchResults.DataSource = requestUrl;&lt;br /&gt;searchResults.DataBind();&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Markup&lt;br /&gt;&lt;/strong&gt;&lt;font face="Courier New"&gt;&amp;lt;skm:rssfeed width="80%" id="searchResults" runat="server" Font-Names="Verdana"&lt;br /&gt;  Font-Size="Medium" CellPadding="5" ShowHeader="False" GridLines="None"&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt; &amp;lt;ItemTemplate&amp;gt;&lt;br /&gt;  &amp;lt;span class="title"&amp;gt;&amp;lt;a href='&amp;lt;%# DataBinder.Eval(Container.DataItem, "Link") %&amp;gt;'&amp;gt;&amp;lt;%# DataBinder.Eval(Container.DataItem, "Title") %&amp;gt;&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;span class="desc"&amp;gt;&amp;lt;%# HighlightSearchTerm(DataBinder.Eval(Container.DataItem, "Description").ToString()) %&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;  &amp;lt;span class="url"&amp;gt;&amp;lt;%# DataBinder.Eval(Container.DataItem, "Link") %&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt; &amp;lt;/ItemTemplate&amp;gt;&lt;br /&gt;  &lt;br /&gt;&amp;lt;/skm:rssfeed&amp;gt;&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;Some example results can be seen &lt;a href="http://scottonwriting.net/Search.aspx?s=ScottOnWriting.NET&amp;amp;count=10&amp;amp;first=1&amp;amp;query=orlando"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is pretty cool, but there are some gotchas.  &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The RSS feed doesn't provide any information if there's more results.  There may be 15 results for the query DataGrid, but the RSS feed, by default, will only return the first 10.  There's no way of knowing for sure if there are more results unless you grab &lt;em&gt;another&lt;/em&gt; RSS feed, this time asking for records starting at 11.  What complicates things is that if there are exactly 10 records, getting the RSS feed starting at 11 won't return nothing; rather it will re-return the first 10 records.  Ick.  My current solution is to just display a Next button if there are 10 records on the page... it's a hack, since it won't really do what is expected for queries that return a multiple of 10 records, but it's good enough.&lt;/li&gt;
&lt;li&gt;I don't know how legal all this is.  If you look at the RSS feed's &lt;font face="Courier New"&gt;&amp;lt;copyright&amp;gt;&lt;/font&gt; tag it says:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Copyright © 2005 Microsoft. All rights reserved. These XML results may not be used, reproduced or transmitted in any manner or for any purpose other than rendering MSN Search results within an RSS aggregator for your personal, non-commercial use. Any other use of these results requires express written permission from Microsoft Corporation. By accessing this web page or using these results in any manner whatsoever, you agree to be bound by the foregoing restrictions.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;I doubt MS is going to care too much if I use these results for my dinky little blog, but clearly they'd care if I was a company that used this approach to provide search on my Web site in lieu of buying Index Server or &lt;a href="http://www.google.com/enterprise/"&gt;Google's searching server&lt;/a&gt;, or whatever.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;Of course, MSN Search is not the first search engine to provide a programmatic means for accessing their results.  Google offers the &lt;a href="http://www.google.com/apis/"&gt;Google API&lt;/a&gt;, a set of Web services that can be used to run queries on Google.  In fact, I've written an article on 4Guys on how to create a search engine with the Google API: &lt;a href="http://aspnet.4guysfromrolla.com/articles/030503-1.aspx"&gt;Searching Google Using the Google Web Service&lt;/a&gt;.  (And I will likely write up an article on using the MSN Search technique...)  The downside of using the Google API is that users are limited to 1,000 queries per day and creating a page to work with the API takes a bit more heavy lifting than just bringing back RSS data and displaying it (although not much more).&lt;/p&gt;
&lt;p&gt;A future blog entry, or 4Guys article, will delve into the MSN Search techniques I used to add search to ScottOnWriting.NET, but don't let that stop you from adding this feature to your site today.  Armed with RssFeed you could do it without further information in a matter of minutes.&lt;/p&gt;&lt;img src="http://scottonwriting.net/aggbug.aspx?PostID=163043" width="1" height="1"&gt;</description><category domain="http://scottonwriting.net/sowblog/archive/tags/ASP.NET+Talk/default.aspx">ASP.NET Talk</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Miscellaneous/default.aspx">Miscellaneous</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Blog+Enhancements/default.aspx">Blog Enhancements</category></item><item><title>Enhancing Your .Text Blog - Allowing Readers to Rate Blog Entries</title><link>http://scottonwriting.net/sowblog/archive/2004/04/15/162908.aspx</link><pubDate>Thu, 15 Apr 2004 20:12:00 GMT</pubDate><guid isPermaLink="false">2814ed8b-42a8-4dfe-b0b1-a7acb3e6d762:162908</guid><dc:creator>Scott Mitchell</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://scottonwriting.net/sowblog/rsscomments.aspx?PostID=162908</wfw:commentRss><comments>http://scottonwriting.net/sowblog/archive/2004/04/15/162908.aspx#comments</comments><description>&lt;p&gt;One of the things I really like about .Text is just how easy it is to customize and enhance it.  Of course, the complete source is available, so you can customize to your heart's content, but I'm talking about customizing it without modifying the source and recompiling.  I've had past blog entries about customizing and digging into .Text (see &lt;a href="http://scottonwriting.net/sowblog/posts/708.aspx"&gt;Giving .Text a Calendar View&lt;/a&gt; and &lt;a href="http://scottonwriting.net/sowblog/posts/930.aspx"&gt;Analyzing your .Text Blog&lt;/a&gt;), and wanted to share my latest enhancement here on ScottOnWriting.NET: the ability for readers to rate a blog entry and leave feedback on why they made their rating (just like how &lt;a href="http://msdn.microsoft.com"&gt;MSDN&lt;/a&gt;'s online articles have a “Rate this feedback“ section at the end of each article).  The end result, you'll agree, looks pretty much just like Microsoft's rating interface, save that mine only allows you to rate from 1 to 5 instead of 1 to 9.  It uses cookies to do a half-assed effort at ensuring that folks only rate a blog entry once.&lt;/p&gt;
&lt;p&gt;If you're interested in adding this rating User Control to your .Text blog, I'll have the source for the User Control and an article discussing it on &lt;a href="http://www.4guysfromrolla.com"&gt;4Guys&lt;/a&gt; sometime next week.  What is cool about .Text (at least .Text 0.94, the version I'm using) is that the page layouts are specified in User Controls themselves (in the &lt;font face="Courier New"&gt;/Skins/&lt;em&gt;skinName&lt;/em&gt;/Controls/&lt;/font&gt; directory).  This means that I could, with just a quick edit in Notepad, adjust the main page so that after each blog entry in addition to the Feedback (&lt;em&gt;xxx&lt;/em&gt;) link, there's also a Rate Entry link, which will take you directly to the interface to link the blog entry.&lt;/p&gt;
&lt;p&gt;The natural extension to this would be to allow users to read / view the most popular (and perhaps least liked) posts...&lt;/p&gt;
&lt;p&gt;(The Rate Entry option is only available by visiting the ScottOnWriting.NET Web site directly.  I guess I could attempt to embed the necessary HTML into the RSS feed, but I doubt I'll do that, since for that (I believe), I &lt;em&gt;will&lt;/em&gt; need to edit the .Text source and recompile/redeploy.)&lt;/p&gt;
&lt;img src="http://scottonwriting.net/aggbug.aspx?PostID=162908" width="1" height="1"&gt;</description><category domain="http://scottonwriting.net/sowblog/archive/tags/ASP.NET+Talk/default.aspx">ASP.NET Talk</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Miscellaneous/default.aspx">Miscellaneous</category><category domain="http://scottonwriting.net/sowblog/archive/tags/Blog+Enhancements/default.aspx">Blog Enhancements</category></item></channel></rss>