November Happy Hour will be moved to Thursday December 5th.

Custom ContentMediaHttpHandler

Vote:
 

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?

#188776
Edited, Mar 02, 2018 15:33
Vote:
 

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.

#188781
Mar 02, 2018 21:04
Vote:
 

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>

#188818
Mar 05, 2018 9:01
Vote:
 

Do you have any more info for me? :)

#188889
Mar 06, 2018 12:49
Vote:
 

Is your specific requirement to vary the viewing of an image depending on whether someone is in a role or not?

#188898
Mar 06, 2018 15:12
Vote:
 

The requirement is to restrict pages, media files (images and documents) to VisitorGroups, and check our role session.

If only IRenderTemplate<IContentMedia> would work...

#188920
Mar 06, 2018 22:06
Vote:
 

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;
        }
}
#188947
Edited, Mar 07, 2018 15:09
Vote:
 

Great you managed to solve it and thanks for sharing the soluton :)!

#188949
Mar 07, 2018 15:13
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.