<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-7019647876740621435</id><updated>2012-02-16T21:31:57.108-06:00</updated><category term='URL Rewriting'/><category term='Login Controls'/><category term='ASP.NET'/><title type='text'>AOnNull</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://aonnull.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7019647876740621435/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://aonnull.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Adam Anderson</name><uri>http://www.blogger.com/profile/17078340429103638232</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7019647876740621435.post-5928668727661371993</id><published>2010-08-17T19:48:00.010-05:00</published><updated>2010-08-18T00:38:21.364-05:00</updated><title type='text'>Dynamic SQL-like Linq  OrderBy Extension</title><content type='html'>&lt;p&gt;So, it's been a while, but I thought I take moment and do my annual blog post ;).&lt;/p&gt;&lt;p&gt;I've been playing around with &lt;a href="http://www.asp.net/mvc"&gt;ASP.NET MVC&lt;/a&gt; and the Linq stuff for &lt;a href="http://sourceforge.net/projects/nhibernate/files/"&gt;NHibernate &lt;/a&gt; recently. I was in need of an OrderBy extension method that could take a SQL-Like OrderBy string and sort a IQueryable&lt;&gt; or IEnumerable&lt;&gt; collection. I wrote up an implementation that worked, but I just wasn't satisfied with its internals (quite a bit of reflection to get the correct type to construct a LambdaExpression, etc)&lt;/p&gt;&lt;p&gt;At any rate, I couldn't leave well enough alone, and, after a bit of Googling, I ran across this &lt;a href="http://stackoverflow.com/"&gt;StackOverflow &lt;/a&gt; answer about &lt;a href="http://stackoverflow.com/questions/41244/dynamic-linq-orderby/233505#233505"&gt;Dynamic LINQ OrderBy&lt;/a&gt;. The extension method wasn't exactly what I was looking for, but that ApplyOrder method is slick, and solved the portion of my implementation that was bothering me.&lt;/p&gt;&lt;p&gt;So, I though I would post up my version in case anybody finds it useful. It handles the following inputs:
&lt;/p&gt;&lt;pre  style="font-family:consolas;"&gt;list.OrderBy(&lt;span style="color: rgb(163, 21, 21);"&gt;"SomeProperty"&lt;/span&gt;);
list.OrderBy(&lt;span style="color: rgb(163, 21, 21);"&gt;"SomeProperty DESC"&lt;/span&gt;);
list.OrderBy(&lt;span style="color: rgb(163, 21, 21);"&gt;"SomeProperty DESC, SomeOtherProperty"&lt;/span&gt;);
list.OrderBy(&lt;span style="color: rgb(163, 21, 21);"&gt;"SomeSubObject.SomeProperty ASC, SomeOtherProperty DESC"&lt;/span&gt;);&lt;/pre&gt;
&lt;span style="font-weight: bold;"&gt;Dynamic &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;SQL-like &lt;/span&gt;&lt;span style="font-weight: bold;"&gt;Linq  OrderBy Extension&lt;/span&gt;

&lt;div style="border: #000080 1px solid; color: #000; font-family: 'Courier New', Courier, Monospace; font-size: 10pt"&gt;
&lt;div style="background-color: #ffffff; overflow: auto; padding: 2px 5px; white-space: nowrap"&gt;    &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;OrderByHelper&lt;/span&gt;&lt;br&gt;
    {&lt;br&gt;
        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; OrderBy&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;T&amp;gt; enumerable, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; orderBy)&lt;br&gt;
        {&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; enumerable.AsQueryable().OrderBy(orderBy).AsEnumerable();&lt;br&gt;
        }&lt;br&gt;
&lt;br&gt;
        &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; OrderBy&amp;lt;T&amp;gt;(&lt;span style="color:#0000ff"&gt;this&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; collection, &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; orderBy)&lt;br&gt;
        {&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;OrderByInfo&lt;/span&gt; orderByInfo &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; ParseOrderBy(orderBy))&lt;br&gt;
                collection = ApplyOrderBy&amp;lt;T&amp;gt;(collection, orderByInfo);&lt;br&gt;
&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; collection;&lt;br&gt;
        }&lt;br&gt;
&lt;br&gt;
        &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; ApplyOrderBy&amp;lt;T&amp;gt;(&lt;span style="color:#2b91af"&gt;IQueryable&lt;/span&gt;&amp;lt;T&amp;gt; collection, &lt;span style="color:#2b91af"&gt;OrderByInfo&lt;/span&gt; orderByInfo)&lt;br&gt;
        {&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;[] props = orderByInfo.PropertyName.Split(&lt;span style="color:#a31515"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;);&lt;br&gt;
            &lt;span style="color:#2b91af"&gt;Type&lt;/span&gt; type = &lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(T);&lt;br&gt;
&lt;br&gt;
            &lt;span style="color:#2b91af"&gt;ParameterExpression&lt;/span&gt; arg = &lt;span style="color:#2b91af"&gt;Expression&lt;/span&gt;.Parameter(type, &lt;span style="color:#a31515"&gt;&amp;quot;x&amp;quot;&lt;/span&gt;);&lt;br&gt;
            &lt;span style="color:#2b91af"&gt;Expression&lt;/span&gt; expr = arg;&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt; (&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; prop &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; props)&lt;br&gt;
            {&lt;br&gt;
                &lt;span style="color:#008000"&gt;// use reflection (not ComponentModel) to mirror LINQ&lt;/span&gt;&lt;br&gt;
                &lt;span style="color:#2b91af"&gt;PropertyInfo&lt;/span&gt; pi = type.GetProperty(prop);&lt;br&gt;
                expr = &lt;span style="color:#2b91af"&gt;Expression&lt;/span&gt;.Property(expr, pi);&lt;br&gt;
                type = pi.PropertyType;&lt;br&gt;
            }&lt;br&gt;
            &lt;span style="color:#2b91af"&gt;Type&lt;/span&gt; delegateType = &lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Func&lt;/span&gt;&amp;lt;,&amp;gt;).MakeGenericType(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(T), type);&lt;br&gt;
            &lt;span style="color:#2b91af"&gt;LambdaExpression&lt;/span&gt; lambda = &lt;span style="color:#2b91af"&gt;Expression&lt;/span&gt;.Lambda(delegateType, expr, arg);&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; methodName = &lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.Empty;&lt;br&gt;
&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (!orderByInfo.Initial &amp;amp;&amp;amp; collection &lt;span style="color:#0000ff"&gt;is&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IOrderedQueryable&lt;/span&gt;&amp;lt;T&amp;gt;)&lt;br&gt;
            {&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (orderByInfo.Direction == &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt;.Ascending)&lt;br&gt;
                    methodName = &lt;span style="color:#a31515"&gt;&amp;quot;ThenBy&amp;quot;&lt;/span&gt;;&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;br&gt;
                    methodName = &lt;span style="color:#a31515"&gt;&amp;quot;ThenByDescending&amp;quot;&lt;/span&gt;;&lt;br&gt;
            }&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;br&gt;
            {&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (orderByInfo.Direction == &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt;.Ascending)&lt;br&gt;
                     methodName = &lt;span style="color:#a31515"&gt;&amp;quot;OrderBy&amp;quot;&lt;/span&gt;;&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;else&lt;/span&gt;&lt;br&gt;
                     methodName = &lt;span style="color:#a31515"&gt;&amp;quot;OrderByDescending&amp;quot;&lt;/span&gt;;&lt;br&gt;
            }&lt;br&gt;
&lt;br&gt;
            &lt;span style="color:#008000"&gt;//TODO: apply caching to the generic methodsinfos?&lt;/span&gt;&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;IOrderedQueryable&lt;/span&gt;&amp;lt;T&amp;gt;)&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;Queryable&lt;/span&gt;).GetMethods().Single(&lt;br&gt;
                method =&amp;gt; method.Name == methodName&lt;br&gt;
                        &amp;amp;&amp;amp; method.IsGenericMethodDefinition&lt;br&gt;
                        &amp;amp;&amp;amp; method.GetGenericArguments().Length == 2&lt;br&gt;
                        &amp;amp;&amp;amp; method.GetParameters().Length == 2)&lt;br&gt;
                .MakeGenericMethod(&lt;span style="color:#0000ff"&gt;typeof&lt;/span&gt;(T), type)&lt;br&gt;
                .Invoke(&lt;span style="color:#0000ff"&gt;null&lt;/span&gt;, &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#0000ff"&gt;object&lt;/span&gt;[] { collection, lambda });&lt;br&gt;
&lt;br&gt;
        }&lt;br&gt;
&lt;br&gt;
        &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;static&lt;/span&gt; &lt;span style="color:#2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="color:#2b91af"&gt;OrderByInfo&lt;/span&gt;&amp;gt; ParseOrderBy(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; orderBy)&lt;br&gt;
        {&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(orderBy))&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;yield&lt;/span&gt; &lt;span style="color:#0000ff"&gt;break&lt;/span&gt;;&lt;br&gt;
&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;[] items = orderBy.Split(&lt;span style="color:#a31515"&gt;&amp;#39;,&amp;#39;&lt;/span&gt;);&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; initial = &lt;span style="color:#0000ff"&gt;true&lt;/span&gt;;&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;foreach&lt;/span&gt;(&lt;span style="color:#0000ff"&gt;string&lt;/span&gt; item &lt;span style="color:#0000ff"&gt;in&lt;/span&gt; items)&lt;br&gt;
            {&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;string&lt;/span&gt;[] pair = item.Trim().Split(&lt;span style="color:#a31515"&gt;&amp;#39; &amp;#39;&lt;/span&gt;);&lt;br&gt;
&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (pair.Length &amp;gt; 2)&lt;br&gt;
                    &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="color:#a31515"&gt;&amp;quot;Invalid OrderBy string &amp;#39;{0}&amp;#39;. Order By Format: Property, Property2 ASC, Property2 DESC&amp;quot;&lt;/span&gt;,item));&lt;br&gt;
&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; prop = pair[0].Trim();&lt;br&gt;
&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt;(&lt;span style="color:#2b91af"&gt;String&lt;/span&gt;.IsNullOrEmpty(prop))&lt;br&gt;
                    &lt;span style="color:#0000ff"&gt;throw&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;ArgumentException&lt;/span&gt;(&lt;span style="color:#a31515"&gt;&amp;quot;Invalid Property. Order By Format: Property, Property2 ASC, Property2 DESC&amp;quot;&lt;/span&gt;);&lt;br&gt;
                &lt;br&gt;
                &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt; dir = &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt;.Ascending;&lt;br&gt;
                &lt;br&gt;
                &lt;span style="color:#0000ff"&gt;if&lt;/span&gt; (pair.Length == 2)&lt;br&gt;
                    dir = (&lt;span style="color:#a31515"&gt;&amp;quot;desc&amp;quot;&lt;/span&gt;.Equals(pair[1].Trim(), &lt;span style="color:#2b91af"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase) ? &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt;.Descending : &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt;.Ascending);&lt;br&gt;
&lt;br&gt;
                &lt;span style="color:#0000ff"&gt;yield&lt;/span&gt; &lt;span style="color:#0000ff"&gt;return&lt;/span&gt; &lt;span style="color:#0000ff"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af"&gt;OrderByInfo&lt;/span&gt;() { PropertyName = prop, Direction = dir, Initial = initial };&lt;br&gt;
&lt;br&gt;
                initial = &lt;span style="color:#0000ff"&gt;false&lt;/span&gt;;&lt;br&gt;
            }&lt;br&gt;
&lt;br&gt;
        }&lt;br&gt;
&lt;br&gt;
        &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;class&lt;/span&gt; &lt;span style="color:#2b91af"&gt;OrderByInfo&lt;/span&gt;&lt;br&gt;
        {&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;string&lt;/span&gt; PropertyName { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt; Direction { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;br&gt;
            &lt;span style="color:#0000ff"&gt;public&lt;/span&gt; &lt;span style="color:#0000ff"&gt;bool&lt;/span&gt; Initial { &lt;span style="color:#0000ff"&gt;get&lt;/span&gt;; &lt;span style="color:#0000ff"&gt;set&lt;/span&gt;; }&lt;br&gt;
        }&lt;br&gt;
&lt;br&gt;
        &lt;span style="color:#0000ff"&gt;private&lt;/span&gt; &lt;span style="color:#0000ff"&gt;enum&lt;/span&gt; &lt;span style="color:#2b91af"&gt;SortDirection&lt;/span&gt;&lt;br&gt;
        {&lt;br&gt;
            Ascending = 0,&lt;br&gt;
            Descending = 1&lt;br&gt;
        }&lt;br&gt;
    }&lt;/div&gt;
&lt;/div&gt;



Anyway, hope someone finds it useful. And if you see any areas that could use some TLC please let me know

A&lt;div class="blogger-post-footer"&gt;© 2010 Adam Anderson. All rights reserved.&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7019647876740621435-5928668727661371993?l=aonnull.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aonnull.blogspot.com/feeds/5928668727661371993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7019647876740621435&amp;postID=5928668727661371993' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7019647876740621435/posts/default/5928668727661371993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7019647876740621435/posts/default/5928668727661371993'/><link rel='alternate' type='text/html' href='http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html' title='Dynamic SQL-like Linq  OrderBy Extension'/><author><name>Adam Anderson</name><uri>http://www.blogger.com/profile/17078340429103638232</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7019647876740621435.post-8643015941677420146</id><published>2009-07-10T20:24:00.002-05:00</published><updated>2009-07-10T22:28:21.875-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Login Controls'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='URL Rewriting'/><title type='text'>URL Rewriting and ASP.NET Login Controls</title><content type='html'>&lt;span style=";font-family:Verdana;font-size:85%;"  &gt;&lt;p style="margin-top: 0px;"&gt;So, this is the initial post to the Blog I set up almost a year ago (How's that for procrastinating). I figure rather than a bunch of boring, all about me, blah blah blah, I would write about an issue I ran into today, that might be of use to someone else. So here goes...&lt;/p&gt;&lt;p&gt;I've recently been working on a .NET WinForms site that employs quite a bit of URL Rewriting. I'm using &lt;a href="http://urlrewriter.net/"&gt;UrlRewriter.NET&lt;/a&gt; to handle the rewriting. I ran up against the issue, &lt;a href="http://weblogs.asp.net/scottgu/archive/2007/02/26/tip-trick-url-rewriting-with-asp-net.aspx#2212636"&gt;mentioned&lt;/a&gt; &lt;a href="http://blah.winsmarts.com/2006/05/12/the-definitive-guide-to-url-rewriting-in-aspnet.aspx"&gt;elsewhere&lt;/a&gt;, with URL rewriting and the ASP.NET Login Controls. Specifically, left in their default state, both the Login control and the LoginStatus control will redirect to the rewritten URL (the one I don't want my users to see) rather than my pretty original URL.&lt;/p&gt;&lt;p&gt;The solution I came up with to fix the issue across all instances of the Login controls in the site, which I hadn't run across on the 'tubes, was to create a simple custom control, employ Request.RawUrl to get the original URL, and use tag mapping to replace the problematic controls.&lt;/p&gt;&lt;p&gt;In order to implement this little fix I needed to add the following two classes to my App_Code directory.
&lt;/p&gt;&lt;p&gt;&lt;strong&gt;New Login Control&lt;/strong&gt;
&lt;/p&gt;&lt;pre&gt;public class UrlRewriteLogin : Login
{
   public override string DestinationPageUrl
   {
       get
       {
           if (String.IsNullOrEmpty(base.DestinationPageUrl))
               return this.Page.Request.RawUrl;

           return base.DestinationPageUrl;
       }
       set
       {
           base.DestinationPageUrl = value;
       }
   }
}
&lt;/pre&gt;&lt;p&gt;The mods to the Login control are fairly straightforward. Using &lt;a href="http://www.red-gate.com/products/reflector/"&gt;.NET Reflector&lt;/a&gt; I can see that the issues arise in the Login Control's private GetRedirectUrl method. When DestinationPageUrl is empty, the method returns Page.Request.Path which shows the underlying URL. If we return the Request.RawUrl from an overridden DestinationPageUrl when the base DestinationPageUrl is blank, we never hit the problematic code, get the desired behavior, and still allow for a custom DestinationPageUrl&lt;/p&gt;&lt;p&gt;&lt;strong&gt;New LoginStatus Control&lt;/strong&gt;
&lt;/p&gt;&lt;pre&gt;public class UrlRewiteLoginStatus : LoginStatus
{
   public override LogoutAction LogoutAction
   {
       get
       {
           if (base.LogoutAction == LogoutAction.Refresh)
               return LogoutAction.Redirect;

           return base.LogoutAction;
       }
       set
       {
           base.LogoutAction = value;
       }
   }

   public override string LogoutPageUrl
   {
       get
       {
           if (base.LogoutAction == LogoutAction.Refresh)
               return this.Page.Request.RawUrl;

           return base.LogoutPageUrl;
       }
       set
       {
           base.LogoutPageUrl = value;
       }
   }
}
&lt;/pre&gt;&lt;p&gt;These mods are a bit more tricky. Again using &lt;a href="http://www.red-gate.com/products/reflector/"&gt;.NET Reflector&lt;/a&gt; I see that the issues arise in the LoginStatus Control's private LogoutClicked method, but only when LogoutAction is Refresh (the default). The problem is the same as above, if the LogoutAction is Refresh, the control uses Page.Request.Path. My solution here was twofold: 1.) Never return a LogoutAction of Refresh, and 2.) When base control's LogoutAction is Refresh, return the Request.RawUrl from LogoutPageUrl. This skips the problematic code, but still allows for normal LogoutPageUrl behavior.&lt;/p&gt;&lt;p&gt;&lt;em&gt;&lt;strong&gt;Note:&lt;/strong&gt;The override of LogoutAction might be a bit confusing to a developer unaware of the hack, as even if you manually set LogoutAction to Refresh, it never returns Refresh from the getter.&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Then, all I needed to do is add the following tagMappings to our web.config. Now, every instance of &lt;asp:login&gt; &amp;lt;asp:Login&amp;gt; and &amp;lt;asp:LoginStatus /&amp;gt; are the new custom controls. w00t!
&lt;/asp:login&gt;&lt;/p&gt;&lt;pre&gt;
&amp;lt;pages&amp;gt;
  &amp;lt;tagMapping&amp;gt;
     &amp;lt;add tagType="System.Web.UI.WebControls.Login"
         mappedTagType="UrlRewriteLogin"/&amp;gt;
     &amp;lt;add tagType="System.Web.UI.WebControls.LoginStatus"
         mappedTagType="UrlRewiteLoginStatus"/&amp;gt;
  &amp;lt;/tagMapping&amp;gt;
&amp;lt;/pages&amp;gt;&lt;/pre&gt;&lt;p&gt;Hope this is useful for someone else.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;© 2010 Adam Anderson. All rights reserved.&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7019647876740621435-8643015941677420146?l=aonnull.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://aonnull.blogspot.com/feeds/8643015941677420146/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7019647876740621435&amp;postID=8643015941677420146' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7019647876740621435/posts/default/8643015941677420146'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7019647876740621435/posts/default/8643015941677420146'/><link rel='alternate' type='text/html' href='http://aonnull.blogspot.com/2009/07/so-this-is-initial-post-to-blog-i-set.html' title='URL Rewriting and ASP.NET Login Controls'/><author><name>Adam Anderson</name><uri>http://www.blogger.com/profile/17078340429103638232</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
