Search code examples
asp.netasp.net-mvcasp.net-mvc-5action-filter

asp.net mvc 5 action filter that renders view as json


In my asp.net mvc 5 application is it possible to write an action filter that will intercept an ActionResult and return a JsonResult containing the rendered view as an html string and the model as json?

Consider this pseudo code:

JSON(new { html = ViewAsHTMLString, model = this.ViewsViewModel })


Solution

  • I use a simple ActionResult method like this in my application:

     return Json(new
                                            {
                                                result = "fail",
                                                html = Extensions.RenderViewToString(ControllerContext, "_Partial_CreatePageContainer", model),
                                                errors = "This page already exists."
                                            });
    

    I then created 2 extension methods to handle the view rendering:

     public static string RenderViewToString(ControllerContext context, string viewName, object model)
            {
                if (string.IsNullOrEmpty(viewName))
                    viewName = context.RouteData.GetRequiredString("action");
    
                var viewData = new ViewDataDictionary(model);
    
                using (var sw = new StringWriter())
                {
                    var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
                    var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
                    viewResult.View.Render(viewContext, sw);
    
                    return sw.GetStringBuilder().ToString();
                }
            }
            public static string RenderViewToString(ControllerContext context, string viewName)
            {
                if (string.IsNullOrEmpty(viewName))
                    viewName = context.RouteData.GetRequiredString("action");
    
                var viewData = new ViewDataDictionary();
    
                using (var sw = new StringWriter())
                {
                    var viewResult = ViewEngines.Engines.FindPartialView(context, viewName);
                    var viewContext = new ViewContext(context, viewResult.View, viewData, new TempDataDictionary(), sw);
                    viewResult.View.Render(viewContext, sw);
    
                    return sw.GetStringBuilder().ToString();
                }
            }