London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

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.