Jul 9, 2012

Xsl Transformation Custome ActionResult

In this post I am creating a custome action result which takes xml data and uses xsl to transform xml data to output page.

Our custome action result will be derived from abstract class ActionResult and need to implement abstract method ExecuteResult. ControllerActionInvoker calls ExecuteResult on the action result returned by the controller action.

In this method we first find the Xsl based on the ViewName and then transform xml using this xsl to generate response output

 public override void ExecuteResult(ControllerContext context)
 {
  if (context == null)
  {
   throw new ArgumentNullException("context");
  }

  if (string.IsNullOrEmpty(ViewName))
  {
   ViewName = context.RouteData.GetRequiredString("action");
  }

  XslCompiledTransform view = FindView(context, ViewName,true);
  
  var response = context.HttpContext.Response.Output;

  RenderView(response, view);
  
 }

Here are the helper method used for used for this.

Based on the viewName, I find view. I am using "~/Views/{1}/{0}.xsl" as ViewLocationFormat. If required more format can be used similar to View engine.

XslCompiledTransform is being cached for performance.


 private static XslCompiledTransform FindView(ControllerContext context, string viewName, bool useCache)
 {
  string controller = context.RouteData.Values["controller"].ToString();

  string keyPath = Path.Combine(controller, viewName);

  string virtualPath = string.Format("~/Views/{1}/{0}.xsl", viewName, controller);
  string viewPath = HttpContext.Current.Server.MapPath(virtualPath);

  // Try the cache           
  if (useCache)
  {
   ObjectCache cache = GetCache();

   if (cache[keyPath] == null)
   {
    XslCompiledTransform xslt = new XslCompiledTransform();
    xslt.Load(viewPath);
    cache[keyPath] = xslt;    
   }

   return cache[keyPath] as XslCompiledTransform;
  }
  else
  {
   XslCompiledTransform xslt = new XslCompiledTransform();
   xslt.Load(viewPath);
   return xslt;
  }
 }
 
 private void RenderView(TextWriter response, XslCompiledTransform view)
 {
  response.Write(TransformXmltoHtml(PageData, view));
    }