Comment rendre une vue partielle dans une chaîne de caractères

j'ai le code suivant:

public ActionResult SomeAction()
{
    return new JsonpResult
    {
        Data = new { Widget = "some partial html for the widget" }
    };
}

j'aimerais le modifier pour que je puisse avoir

public ActionResult SomeAction()
{
    // will render HTML that I can pass to the JSONP result to return.
    var partial = RenderPartial(viewModel); 
    return new JsonpResult
    {
        Data = new { Widget = partial }
    };
}

est-ce possible? Quelqu'un pourrait expliquer comment?

remarque:, j'ai édité la question avant de poster la solution.

40
demandé sur DaveDev 2010-03-29 16:20:23

8 réponses

j'ai opté pour une méthode d'extension comme la suivante pour un ASP.NET MVC 4 app. Je pense que c'est plus simple que certaines des suggestions que j'ai vu:

public static class ViewExtensions
{
    public static string RenderToString(this PartialViewResult partialView)
    {
        var httpContext = HttpContext.Current;

        if (httpContext == null)
        {
            throw new NotSupportedException("An HTTP context is required to render the partial view to a string");
        }

        var controllerName = httpContext.Request.RequestContext.RouteData.Values["controller"].ToString();

        var controller = (ControllerBase)ControllerBuilder.Current.GetControllerFactory().CreateController(httpContext.Request.RequestContext, controllerName);

        var controllerContext = new ControllerContext(httpContext.Request.RequestContext, controller);

        var view = ViewEngines.Engines.FindPartialView(controllerContext, partialView.ViewName).View;

        var sb = new StringBuilder();

        using (var sw = new StringWriter(sb))
        {
            using (var tw = new HtmlTextWriter(sw))
            {
                view.Render(new ViewContext(controllerContext, view, partialView.ViewData, partialView.TempData, tw), tw);
            }
        }

        return sb.ToString();
    }
}

Il me permet de faire ce qui suit:

var html = PartialView("SomeView").RenderToString();

en outre, cette approche persiste tout Modèle, ViewBag et d'autres données d'affichage pour l'affichage.

37
répondu Ted Nyberg 2013-10-06 19:36:07

C'est une version légèrement modifiée d'une réponse qui fonctionne:

public static string RenderPartialToString(string controlName, object viewData)
{
    ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };

    viewPage.ViewData = new ViewDataDictionary(viewData);
    viewPage.Controls.Add(viewPage.LoadControl(controlName));

    StringBuilder sb = new StringBuilder();
    using (StringWriter sw = new StringWriter(sb))
    {
        using (HtmlTextWriter tw = new HtmlTextWriter(sw))
        {
            viewPage.RenderControl(tw);
        }
    }

    return sb.ToString();
}

Utilisation:

string ret = RenderPartialToString("~/Views/MyController/MyPartial.ascx", model);
21
répondu DaveDev 2017-01-09 10:45:50

la réponse de DaveDev a bien fonctionné pour moi, cependant quand la vue partielle appelle une autre partie j'obtiens "la valeur ne peut pas être nulle. Nom du paramètre: afficher"

en cherchant autour de moi j'ai fait une variante du suivant cela semble bien fonctionner.

 public static string RenderPartialToString(string viewName, object model, ControllerContext ControllerContext)
    {
        if (string.IsNullOrEmpty(viewName))
            viewName = ControllerContext.RouteData.GetRequiredString("action");
        ViewDataDictionary ViewData = new ViewDataDictionary();
        TempDataDictionary TempData = new TempDataDictionary();
        ViewData.Model = model;

        using (StringWriter sw = new StringWriter())
        {
            ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
            ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
            viewResult.View.Render(viewContext, sw);

            return sw.GetStringBuilder().ToString();
        }

    }

Utilisation:

String result = MVCHelpers.RenderPartialToString("PartialViewHere", Model, ControllerContext)
8
répondu Vdex 2011-04-27 08:51:36

vous pouvez créer une extension qui rend la vue en chaîne.

public static class RenderPartialToStringExtensions
{
    /// <summary>
    /// render PartialView and return string
    /// </summary>
    /// <param name="context"></param>
    /// <param name="partialViewName"></param>
    /// <param name="model"></param>
    /// <returns></returns>
    public static string RenderPartialToString(this ControllerContext context, string partialViewName, object model)
    {
        return RenderPartialToStringMethod(context, partialViewName, model);
    }

    /// <summary>
    /// render PartialView and return string
    /// </summary>
    /// <param name="context"></param>
    /// <param name="partialViewName"></param>
    /// <param name="viewData"></param>
    /// <param name="tempData"></param>
    /// <returns></returns>
    public static string RenderPartialToString(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData)
    {
        return RenderPartialToStringMethod(context, partialViewName, viewData, tempData);
    }

    public static string RenderPartialToStringMethod(ControllerContext context, string partialViewName, ViewDataDictionary viewData, TempDataDictionary tempData)
    {
        ViewEngineResult result = ViewEngines.Engines.FindPartialView(context, partialViewName);

        if (result.View != null)
        {
            StringBuilder sb = new StringBuilder();
            using (StringWriter sw = new StringWriter(sb))
            {
                using (HtmlTextWriter output = new HtmlTextWriter(sw))
                {
                    ViewContext viewContext = new ViewContext(context, result.View, viewData, tempData, output);
                    result.View.Render(viewContext, output);
                }
            }

            return sb.ToString();
        }
        return String.Empty;
    }

    public static string RenderPartialToStringMethod(ControllerContext context, string partialViewName, object model)
    {
        ViewDataDictionary viewData = new ViewDataDictionary(model);
        TempDataDictionary tempData = new TempDataDictionary();
        return RenderPartialToStringMethod(context, partialViewName, viewData, tempData);
    }
}

Et ensuite l'utiliser dans l'action

[HttpPost]
public ActionResult GetTreeUnit(string id)
{
    int _id = id.ExtractID();
    string render = ControllerContext.RenderPartialToString("SomeView");
    return Json(new { data = render });
}
7
répondu Sasha Fentsyk 2016-07-23 19:13:45

fonctionne parfaitement (seulement afficher le nom requis)

* pour les paramètres, vous pouvez utiliser un modèle

* peut appeler cette fonction à partir d'un point de vue aussi

voir le côté ou en Appelant le Côté

BuyOnlineCartMaster ToInvoice1 = new BuyOnlineCartMaster(); // for passing parameters
ToInvoice1.CartID = 1;

string HtmlString = RenderPartialViewToString("PartialInvoiceCustomer", ToInvoice1);

fonction générant HTML

 public static string RenderPartialViewToString(string viewName, object model)
  {    
     using (var sw = new StringWriter())
            {
                BuyOnlineController controller = new BuyOnlineController(); // instance of the required controller (you can pass this as a argument if needed)

                // Create an MVC Controller Context
                var wrapper = new HttpContextWrapper(System.Web.HttpContext.Current);

                RouteData routeData = new RouteData();

                routeData.Values.Add("controller", controller.GetType().Name
                                                            .ToLower()
                                                            .Replace("controller", ""));

                controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);

                controller.ViewData.Model = model;

                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.ToString();
            }
   }
2
répondu Arun Prasad E S 2016-09-02 05:35:44

Dave,

        protected static string RenderPartialToString(Controller controller, string partialName, object model)
    {
        var vd = new ViewDataDictionary(controller.ViewData);
        var vp = new ViewPage
        {
            ViewData = vd,
            ViewContext = new ViewContext(),
            Url = new UrlHelper(controller.ControllerContext.RequestContext)
        };

        ViewEngineResult result = ViewEngines
                                  .Engines
                                  .FindPartialView(controller.ControllerContext, partialName);

        if (result.View == null)
        {
            throw new InvalidOperationException(
            string.Format("The partial view '{0}' could not be found", partialName));
        }
        var partialPath = ((WebFormView)result.View).ViewPath;

        vp.ViewData.Model = model;

        Control control = vp.LoadControl(partialPath);
        vp.Controls.Add(control);

        var sb = new StringBuilder();

        using (var sw = new StringWriter(sb))
        {
            using (var tw = new HtmlTextWriter(sw))
            {
                vp.RenderControl(tw);
            }
        }
        return sb.ToString();
    }

utilisation dans le controller:

        public string GetLocationHighlites()
    {
        IBlockData model = WebPagesMapper.GetLocationHighlites();
        // **this** being the controoler instance
        // LocationPartial.ascx can be defined in shared or in view folder
        return RenderPartialToString(**this**,"LocationPartial", model);
    }
1
répondu jim tollan 2010-03-30 09:37:35

Vous pouvez faire hors de la boîte avec:

var partial = new HtmlString(Html.Partial("_myPartial", Model).ToString());
1
répondu Dan P 2017-10-03 12:36:54
public virtual string RenderPartialViewToString(string viewName, object viewmodel)
        {
            if (string.IsNullOrEmpty(viewName))
            {
                viewName = this.ControllerContext.RouteData.GetRequiredString("action");
            }

            ViewData.Model = viewmodel;

            using (var sw = new StringWriter())
            {
                ViewEngineResult viewResult = System.Web.Mvc.ViewEngines.Engines.FindPartialView(this.ControllerContext, viewName);
                var viewContext = new ViewContext(this.ControllerContext, viewResult.View, this.ViewData, this.TempData, sw);
                viewResult.View.Render(viewContext, sw);
                viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);

                return sw.GetStringBuilder().ToString();
            }
        }
0
répondu Krishna Soni 2017-11-28 07:01:53