Sunday, November 2, 2014

Glimpse Timeline messages with EPiServer MVC

Glimpse is a powerful tool for monitoring and diagnosing problems in your website. But when used with EPiServer MVC, inspection of routes and modelbinding needs to be disabled.

You can get ActionExecuting/ActionExecuted messages shown in the Glimpse Timeline by using a custom action filter.


The action filter publishes timeline messages to Glimpse
 public class GlimpseFilter : IActionFilter
 {
   public void OnActionExecuting(ActionExecutingContext filterContext)
   {
     IExecutionTimer executionTimer = GlimpseHelper.GetExecutionTimer();
     IMessageBroker messageBroker = GlimpseHelper.GetMessageBroker();
     if (executionTimer != null && messageBroker != null)
     {
       var timelineMessage = new ActionFilter.OnActionExecuting.Message()
         .AsTimedMessage(executionTimer.Point())
         .AsActionMessage(filterContext.Controller)
         .AsChildActionMessage(filterContext.Controller)
         .AsFilterMessage(FilterCategory.Action, typeof(ActionExecutingContext))
         .AsBoundedFilterMessage(FilterBounds.Executing)
         .AsMvcTimelineMessage(MvcTimelineCategory.Filter);
       messageBroker.Publish(timelineMessage);
     }
   }

   public void OnActionExecuted(ActionExecutedContext filterContext)
   {
     IExecutionTimer executionTimer = GlimpseHelper.GetExecutionTimer();
     IMessageBroker messageBroker = GlimpseHelper.GetMessageBroker();
     if (executionTimer != null && messageBroker != null)
     {
       var timelineMessage = new ActionFilter.OnActionExecuted.Message()
         .AsTimedMessage(executionTimer.Point())
         .AsActionMessage(filterContext.Controller)
         .AsChildActionMessage(filterContext.Controller)
         .AsFilterMessage(FilterCategory.Action, typeof(ActionExecutedContext))
         .AsBoundedFilterMessage(FilterBounds.Executed)
         .AsMvcTimelineMessage(MvcTimelineCategory.Filter);
       messageBroker.Publish(timelineMessage);
     }
   }
 }
A GlimpseHelper class is used to create and publish message
 public static class GlimpseHelper
 {
   private const string GlimpseRuntimeApplicationKey = "__GlimpseRuntime";
   private const string GlimpseExecutionTimerDataStoreKey = "__GlimpseTimer";

   public static GlimpseRuntime GetRuntime()
   {
     if (HttpContext.Current == null || HttpContext.Current.Application == null)
     {
       return null;
     }
     return HttpContext.Current.Application.Get(GlimpseRuntimeApplicationKey) as GlimpseRuntime;
   }

   public static IMessageBroker GetMessageBroker()
   {
     GlimpseRuntime glimpseRuntime = GetRuntime();
     if (glimpseRuntime == null || glimpseRuntime.Configuration == null)
     {
       return null;
     }

     return glimpseRuntime.Configuration.MessageBroker;
   }

   public static IExecutionTimer GetExecutionTimer()
   {
     GlimpseRuntime glimpseRuntime = GetRuntime();
     if (glimpseRuntime == null || glimpseRuntime.Configuration == null || glimpseRuntime.Configuration.FrameworkProvider == null)
     {
       return null;
     }

     IDataStore httpRequestStore = glimpseRuntime.Configuration.FrameworkProvider.HttpRequestStore;
     if (httpRequestStore == null)
     {
       return null;
     }
     return httpRequestStore.Get(GlimpseExecutionTimerDataStoreKey);
   }
 }

Thursday, March 20, 2014

Posting from an EPiServer MVC block

When Posting to a custom Action, we go outside the normal EPiServer context, so EPiServer cannot resolve a "currentBlock" parameter or current language.
 @using (Html.BeginForm("SomeAction", "MyBlock"))   
 {   
   <input type="submit" />  
 }

The Action URL will be something like "/MyBlock/SomeAction", which is different from the current page URL.
We need to manually redirect the browser back to the current page URL. For example by maintaining a CurrentPageLink and CurrentLanguage in the view model.
 [HttpPost]  
 public ActionResult SomeAction(MyViewModel viewModel)  
 {   
   return new RedirectResult(_urlResolver.GetUrl(viewModel.CurrentPageLink, viewModel.CurrentLanguage));  
 }  
This can be simplified by using language specific forms.