Yes, this happens in the url rewriter.
You can write your own and handle the redirect in a nicer way.
In what method in the rewriter? They already have a custom one, so it wouldn't be a big stretch to override something else.
It happens in:
public override bool TryConvertToInternal(UrlBuilder url, out CultureInfo preferredCulture, out object internalObject)
{
}
I think there is just a simple check like this:
if (!url.Path.EndsWith("/"))
{
HttpContext.Current.Response.Redirect(url.Path + "/" + url.Query + url.Fragment);
}
Oh, this goes for 6 R2, in earlier versions the method is just called ConvertToInternal.
Your client is right. It really should be a 301 so someone ought to get it filed as a bug.
It's actually not in the FriendlyUrlRewriter. Rather, it's out in the UrlRewriteModule. The FriendlyUrlRewriter just returns something called a RedirectPageReference, which the module picks up.
I think I was able to fix this by extended UrlWriteModule, overriding one method, and changing about three lines of code. Based on my testing, this works correctly.
using System.Web;
using EPiServer.Core;
using EPiServer.Web;
using log4net;
namespace EPiServer
{
public class CorrectedUrlRewriteModule : UrlRewriteModule
{
private static ILog _log = LogManager.GetLogger(typeof(UrlRewriteModule));
protected override void HttpUrlRewriteToInternal(UrlBuilder url)
{
UrlRewriteEventArgs e = new UrlRewriteEventArgs(url, new UrlRewriteEventArgs.Context(this.UrlInternal, this.UrlExternal));
this.OnHttpRewritingToInternal(e);
if (e.Cancel)
{
if (!_log.IsDebugEnabled)
return;
_log.DebugFormat("Further URL rewriting stopped. Returning URL {0}", (object)e.Url);
}
else
{
Global.UrlRewriteProvider.ValidateRewriteToInternal(e, this.UrlExternal.Path);
if (e.Cancel)
{
if (!_log.IsDebugEnabled)
return;
_log.DebugFormat("Url is not valid for rewrite. Returning URL {0}", (object)e.Url);
}
else
{
object internalObject;
if (Global.UrlRewriteProvider.ConvertToInternal(e.Url, out internalObject))
{
if (internalObject is RedirectPageReference)
{
// This is the only code that has changed in this overridden method. This changes the redirect from the default 302 to a 301.
HttpContext.Current.Response.StatusCode = 301;
HttpContext.Current.Response.StatusDescription = "Moved Permanently";
HttpContext.Current.Response.RedirectLocation = (string) e.Url;
HttpContext.Current.ApplicationInstance.CompleteRequest();
return;
}
else
{
e.IsModified = true;
PageReference pageReference = internalObject as PageReference;
if (_log.IsDebugEnabled)
_log.DebugFormat("Returning URL {0} as PageReference {0}", (object)e.Url, pageReference == (PageReference)null ? (object)"(NULL)" : (object)pageReference.ToString());
}
}
else if (_log.IsDebugEnabled)
_log.DebugFormat("Returning URL {0}", (object)e.Url.ToString());
this.OnHttpRewroteToInternal(e);
}
}
}
}
}
We've found a bizarre problem with this, and I have no idea how to fix it. Our app is running in a Virtual Directory. When you have an EPiServer page that shortcuts to a page on the same server (same domain), but not in the same Virtual Directory, you get this:
The virtual path '/beneficiary/FeePayment/AcctInfo.aspx' maps to another application, which is not allowed.
I only changed those four lines of code, so I have NO idea where this error could be coming from.
HI All
The solution by "Deane Barker" is the correct one with change in "UrlRewriteModule
". Fully tested and works great.
Thanks
Kind Regards
Sandeep
If I were to use Deane Barkers UrlRewriteModule-solution, how do I configure EPi to use it? Is it in episerver.config ?
All the best
Linus
In case somebody is interested: you have to set the type to the namespace and dll name of the 'UrlRewriteModule' in the web.config
When a request comes in for a page without a trailing slash, EPiServer redirects it to the same page but with a trailing slash. However, it does this with a 302 Found, instead of a 301 Moved Permanently.
I think this is EPiServer-specific behavior, not IIS behavior. I found an ASP.Net site not running EPiServer, and used Curl to request a directory without the trailing slash. It redirected me with a 301, rather than a 302. So, somewhere, EPiServer is specifically using a 302, and my client wants a 301.
Is there any way to change this?