To handle AJAX form requests in my ASP.NET MVC3 controller I needed a way to render a partial view to a string to return a JSON result containing both the (server-side) validation result (as boolean) and a rendered partial view (as string).
Unfortunately in ASP.NET MVC3 there seems no out-of-the-box support for rendering partial views to strings, but I found this create post ASP.NET MVC Render Partial View to String which shows how to implement a RenderPartialViewToString method. To avoid the need of a parent class for each controller that implements this (helper) method I decided to use the following extension methods:
/// <summary> /// Controller extension class that adds controller methods /// to render a partial view and return the result as string. /// /// Based on http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/ /// </summary> public static class ControllerExtension { /// <summary> /// Renders a (partial) view to string. /// </summary> /// <param name="controller">Controller to extend</param> /// <param name="viewName">(Partial) view to render</param> /// <returns>Rendered (partial) view as string</returns> public static string RenderPartialViewToString(this Controller controller, string viewName) { return controller.RenderPartialViewToString(viewName, null); } /// <summary> /// Renders a (partial) view to string. /// </summary> /// <param name="controller">Controller to extend</param> /// <param name="viewName">(Partial) view to render</param> /// <param name="model">Model</param> /// <returns>Rendered (partial) view as string</returns> public static string RenderPartialViewToString(this Controller controller, string viewName, object model) { if (string.IsNullOrEmpty(viewName)) viewName = controller.ControllerContext.RouteData.GetRequiredString("action"); controller.ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } } |
Using this extension methods my controller actions handling the AJAX requests look like this:
[HttpPost] public ActionResult Update(int id, Model model) { if (ModelState.IsValid) { // Update the database [...] // Partial/FormUpdated contains a success message return Json(new Object[] { true, this.RenderPartialViewToString("Partial/FormUpdated", model) }); } // Partial/Form contains the form with all server-side validation errors return Json(new Object[] { false, this.RenderPartialViewToString("Partial/Form", model) }); } |