0

I need to use the html generated by a razor template in one of my controllers, an abstract one actually to handle ajax lists. That way I can have a generic ajax list implementation which will work for any type of model, and provide the standard operations like add/edit/delete ...

Since I'd like to generate the list elements on the server, I thought I could make razor templates for each element, and then return the generated html (for a new element, or for editing an element) in a JSON object like this:

  • a flag to tell if the operation was successful
  • an error field to describe the error (if there was one)
  • the generated html

At first I thought about instantiating an HtmlHelper (as explained here: HtmlHelper in controller) and using the EditorFor method, but I'm wondering if this a good way to achieve this, since creating an instance of HtmlHelper seems to be quite a time consuming operation.

Is there a simple way to execute the right razor template and get the html in a string?

Also is there a better way to implement such a generic behavior?

Community
  • 1
  • 1
ppetrov
  • 3,077
  • 2
  • 15
  • 27
  • Your question is a bit vague. Are you returning JSON with a (partial) view as one of the object properties? – Erik Philips Sep 03 '13 at 15:12
  • Updated the question, yes I will be returning JSON, but I won't use partial views, since the html for the model is also generated elsewhere using razor templates – ppetrov Sep 03 '13 at 15:15
  • Don't confuse the function Partial, with what a partial view is. This appears to be an [XY Problem](http://meta.stackexchange.com/a/66378). I believe you are attempting to return html (view or partial view) in a JSON result. However instead of asking this question, you have a solution that isn't working and are asking how to make that work instead. – Erik Philips Sep 03 '13 at 15:20
  • 1
    possible duplicate of [How to Render Partial View or View into a String](http://stackoverflow.com/questions/2537741/how-to-render-partial-view-into-a-string) – Erik Philips Sep 03 '13 at 15:21
  • @ErikPhilips the link you posted works for ascx controls, but apparently not for razor as said in a comment on the accepted answer, but this seems to answer my question (not entirely since it still is about partial views and not razor templates, but it's close) : http://stackoverflow.com/questions/5532345/render-partial-to-string-in-the-controller-or-elsewhere/8677839#8677839 (didn't think of looking for render partial view, I only looked for "render razor template") – ppetrov Sep 03 '13 at 15:39

1 Answers1

4

I created a method that does the trick. My reason for creating the method was the same as yours; I wanted to return a JsonResult that contained not only the markup but some other data as well.

public string RenderPartialViewToString(string viewName, object model, ViewDataDictionary viewData = null)
{
    ViewData.Model = model;

    if (viewData != null)
        foreach (KeyValuePair<string, object> item in viewData)
            ViewData.Add(item);

    using (var sw = new System.IO.StringWriter())
    {
        var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
        var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
        viewResult.View.Render(viewContext, sw);
        viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
        return sw.GetStringBuilder().ToString();
    }
}

I placed this method in my base controller so all my controllers have access to it.

asymptoticFault
  • 4,491
  • 2
  • 19
  • 24
  • Seems to be what I'm looking for, but here you have to tell which view to use, does this mean I'll have to write the code to find the right razor template (partial view) for my model or is there an already existing method to do that? – ppetrov Sep 03 '13 at 15:24
  • @ppetrov Correct you do have to specify the name of the Partial View, but the code will find it based on the name, `.FindPartialView(ControllerContext, viewName)`. You're saying you won't know the name of the Partial View? – asymptoticFault Sep 03 '13 at 15:28
  • I could know it using reflection, but I'd like to avoid that and use the razor mechanism to find the right view. The models will have attributes like `UIHint` so it seems to me that I'd be reinventing the wheel if I try to find the right view myself – ppetrov Sep 03 '13 at 15:31
  • @ppetrov So all you will know is the Model Type and you want the template to be dynamically retrieved based on which template has that Type as its Model? That sounds more like a custom Editor Template. – asymptoticFault Sep 03 '13 at 15:46
  • yes that's what I'd like to do, and it does sound like a custom Editor Template, but since there already is one in mvc, I'd like to use it – ppetrov Sep 03 '13 at 15:49
  • @ppetrov Well Editor Templates are named for the Type they render so if you follow the same pattern the above solution could still work. – asymptoticFault Sep 03 '13 at 16:00