301 Redirect for Media Item

We recently had a requirement about 301 redirect for media item like pdf files. Sitecore Shared Source 301 Redirect module was used for 301 redirect, but it does not support 301 redirect for media item requested url, because sitecore MediaRequestHandler redirect to ItemNotFoundUrl, if requested URL does not exist in sitecore.

CustomMediaRequestHandler allows you to extend the default MediaRequestHandler, so you can easily check if the requested media Url from redirect url module, does not exist in sitecore media library, then get value of “Redirect to Item” or “Redirect to Url”, and redirect web request on these value.

Custom DoRedirect function process if request media is not in sitecore.

Because this configuration is not within the /configuration/sitecore element, this requires one or two updates to the /web.config file itself. Under the /configuration/system.webServer/handlers element:

<!–<add verb=”*” path=”sitecore_media.ashx” type=”Sitecore.Resources.Media.MediaRequestHandler, Sitecore.Kernel” name=”Sitecore.MediaRequestHandler”/>–>
<add verb=”*” path=”sitecore_media.ashx” type=”Project.Framework.CustomMediaRequestHandler, Project.Framework” name=”Sitecore.MediaRequestHandler”/>

public class CustomMediaRequestHandler : MediaRequestHandler
{
protected override bool DoProcessRequest(HttpContext context)
{
Assert.ArgumentNotNull((object)context, “context”);
MediaRequest request = MediaManager.ParseMediaRequest(context.Request);
if (request == null)
return false;
Media media = MediaManager.GetMedia(request.MediaUri);
if (media != null)
return this.DoProcessRequest(context, request, media);
using (new SecurityDisabler())
media = MediaManager.GetMedia(request.MediaUri);
string str;
if (media == null)
{
str = DoRedirect(context) ? string.Empty : Settings.ItemNotFoundUrl;
}
else
{
Assert.IsNotNull((object)Context.Site, “site”);
str = Context.Site.LoginPage != string.Empty ? Context.Site.LoginPage : Settings.NoAccessUrl;
}
if (!string.IsNullOrEmpty(str))
{
if (Settings.RequestErrors.UseServerSideRedirect)
HttpContext.Current.Server.Transfer(str);
else
HttpContext.Current.Response.Redirect(str);
}
return true;
}

private IEnumerable<Item> GetRedirects(Database db, string templateName, string versionedTemplateName, string queryType)
{
IEnumerable<Item> enumerable = (IEnumerable<Item>)null;

string setting = Sitecore.Configuration.Settings.GetSetting(SharedSource.RedirectModule.Constants.Settings.RedirectRootNode);

switch (queryType)
{
case “fast”:
IEnumerable<Item> first = (IEnumerable<Item>)db.SelectItems(string.Format(“fast:{0}//*[@@templatename='{1}']“, (object)setting, (object)templateName));
IEnumerable<Item> source = (IEnumerable<Item>)db.SelectItems(string.Format(“fast:{0}//*[@@templatename='{1}']“, (object)setting, (object)versionedTemplateName));
enumerable = Enumerable.Any<Item>(source, (Func<Item, bool>)(i => i.Versions.Count > 0)) ? Enumerable.Union<Item>(first, Enumerable.Where<Item>(source, (Func<Item, bool>)(i => i.Versions.Count > 0))) : first;
break;
case “query”:
enumerable = (IEnumerable<Item>)db.SelectItems(string.Format(“{0}//*[@@templatename='{1}' or @@templatename='{2}']“, (object)setting, (object)templateName, (object)versionedTemplateName));
break;
default:
Item obj = db.SelectSingleItem(setting);
if (obj != null)
{
enumerable = Enumerable.Where<Item>((IEnumerable<Item>)obj.Axes.GetDescendants(), (Func<Item, bool>)(i => i.TemplateName == templateName || i.TemplateName == versionedTemplateName));
break;
}
else
break;
}
return enumerable ?? (IEnumerable<Item>)new Item[0];
}

protected bool DoRedirect(HttpContext context)
{
string input = HttpContext.Current.Request.Url.ToString();
string absolutePath = HttpContext.Current.Request.Url.AbsolutePath;

Database database = Context.Database;

//bool isRedirectUrl = false;
Item redirectUrlItem = null;
foreach (Item redirectItem in GetRedirects(database, SharedSource.RedirectModule.Constants.Templates.RedirectUrl, SharedSource.RedirectModule.Constants.Templates.VersionedRedirectUrl, Sitecore.Configuration.Settings.GetSetting(SharedSource.RedirectModule.Constants.Settings.QueryExactMatch)))
{
if (input.Equals(redirectItem[SharedSource.RedirectModule.Constants.Fields.RequestedUrl], StringComparison.OrdinalIgnoreCase) ||
absolutePath.Equals(redirectItem[SharedSource.RedirectModule.Constants.Fields.RequestedUrl],
StringComparison.OrdinalIgnoreCase))
{
//isRedirectUrl = true;
redirectUrlItem = redirectItem;
break;
}
}

if (redirectUrlItem != null)
{
context.Response.StatusCode = 301;
if (!string.IsNullOrEmpty(redirectUrlItem[SharedSource.RedirectModule.Constants.Fields.RedirectToItem]))
{

var sitecoreItem = redirectUrlItem[SharedSource.RedirectModule.Constants.Fields.RedirectToItem];
var item = Sitecore.Context.Database.GetItem(sitecoreItem);
//MediaItem mediaItem = item;

var isMediaItem = MediaManager.HasMediaContent(item);

if (isMediaItem)
{
var mediaItemUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + MediaManager.GetMediaUrl(item);
context.Response.AddHeader(“Location”, mediaItemUrl);
return true;
}

var redirecturl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority) + LinkManager.GetItemUrl(item);
context.Response.AddHeader(“Location”, redirecturl);
return true;
}
if (!string.IsNullOrEmpty(redirectUrlItem[SharedSource.RedirectModule.Constants.Fields.RedirectToUrl]))
{
var redirecturl = redirectUrlItem[SharedSource.RedirectModule.Constants.Fields.RedirectToUrl];

context.Response.AddHeader(“Location”, redirecturl);
return true;
}

}

return false;
}
}

This way we can 301 redirect for sitecore media item .

 

Share thisEmail this to someonePrint this pageTweet about this on Twitter0Share on Facebook0Share on Google+0Share on TumblrShare on LinkedIn0
0 votes

Leave a Reply

Your email address will not be published. Required fields are marked *


3 − = zero

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>