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)); }