Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
Five New Optimizely Certifications are Here! Validate your expertise and advance your career with our latest certification exams. Click here to find out more
Hi what is your requirement? They may be other approaches which can solve your need, for example you could consider using a content event to hook onto the ContentLoading event.
We have this:
[VisitorGroupCriterion(Category = "Member", DisplayName = "Member role", Description = "")] public class UserRoleCriterion : CriterionBase<UserRoleModel> { public override bool IsMatch(IPrincipal principal, HttpContextBase httpContext) { if (httpContext?.Session == null) return httpContext.Handler is ContentMediaHttpHandler; if (SessionHelper.Current == null) return false; var userRoles = SessionHelper.Current.UserRoles; return userRoles != null && userRoles.Any() && userRoles.Any(r => r.Name == Model.Condition); } } public class UserRoleModel : CriterionModelBase { [Required, DojoWidget(SelectionFactoryType = typeof(RolesSelectionFactory))] public string Condition { get; set; } public override ICriterionModel Copy() { return ShallowCopy(); } }
But when loading files the contex is ContentMediaHttpHandler, and it has no session.
If only I can override the handler with my own, it will work. I works fine with IRenderTemplate<IContentImage> but not with IRenderTemplate<IContentMedia>
Is your specific requirement to vary the viewing of an image depending on whether someone is in a role or not?
The requirement is to restrict pages, media files (images and documents) to VisitorGroups, and check our role session.
If only IRenderTemplate<IContentMedia> would work...
My solution to change ContentMediaHttpHandler to custom handler:
[ModuleDependency(typeof(EPiServer.Web.InitializationModule))] public class HandlerInitialization : IInitializableModule { public void Initialize(InitializationEngine context) { context.Locate.TemplateResolver().TemplateResolved += TemplateCoordinator.OnHandlerTemplateResolved; } public void Uninitialize(InitializationEngine context) { ServiceLocator.Current.GetInstance<TemplateResolver>().TemplateResolved -= TemplateCoordinator.OnHandlerTemplateResolved; } public void Preload(string[] parameters) { } }
Change Template:
public class TemplateCoordinator { public static void OnHandlerTemplateResolved(object sender, TemplateResolverEventArgs args) { if (args.SelectedTemplate == null || args.SelectedTemplate.TemplateType != typeof(ContentMediaHttpHandler)) return; var mediaHandler = args.SupportedTemplates .SingleOrDefault(r => r.Name.Contains("CustomContentMediaHttpHandler") && r.TemplateTypeCategory == args.SelectedTemplate.TemplateTypeCategory); if (mediaHandler != null) args.SelectedTemplate = mediaHandler; } }
Hello
I have a custom ContentMediaHttpHandler:
[TemplateDescriptor(Inherited = true, TemplateTypeCategory = TemplateTypeCategories.HttpHandler)] public class CustomContentMediaHttpHandler : BlobHttpHandler, IRenderTemplate, IRequiresSessionState
{
protected override Blob GetBlob(HttpContextBase httpContext)
{
//This the implementation from ContentMediaHttpHandler
var customRouteData = httpContext.Request.RequestContext.GetCustomRouteData(DownloadMediaRouter.DownloadSegment);
if (!string.IsNullOrEmpty(customRouteData))
{
httpContext.Response.AppendHeader("Content-Disposition",
$"attachment; filename=\"{customRouteData}\"; filename*=UTF-8''{Uri.EscapeDataString(customRouteData)}");
}
var binaryStorable = ServiceLocator.Current.GetInstance().Content as IBinaryStorable;
return binaryStorable?.BinaryData;
}
}
I need to extend it with IRequiredSessionState to check a saved session in a CriterionBase<>.
But my handler doesnt run, only standard ContentMediaHttpHandler is running.
If I change to IRenderTemplate it will work for images, but not documents.
What is the problem?