web-dev-qa-db-fra.com

Obtenir le code HTML d'une vue partielle depuis l'intérieur du contrôleur

J'ai développé un mécanisme simple pour mon site web mvc pour extraire le html via jquery qui renseigne ensuite un div spécifié. Tout va bien et ça a l'air cool.
Mon problème est que je crée maintenant un balisage HTML dans mon contrôleur (ce qui est très facile à faire avec VB.net btw).

Est-il possible d'utiliser un 'Contrôle utilisateur MVC View' personnalisé pour répondre à ce besoin? Puis-je créer une instance d'un contrôle, transmettre les données du modèle et le rendre au format HTML? Ce serait alors une simple question de rendu et de renvoi au navigateur appelant.

27
Andrew Harry

Vous avez plusieurs options.

Créez un contrôle utilisateur de vue MVC et un gestionnaire d’actions dans votre contrôleur pour la vue. Pour rendre la vue, utilisez 

<% Html.RenderPartial("MyControl") %>

Dans ce cas, votre gestionnaire d’actions devra transmettre les données du modèle à la vue.

public ActionResult MyControl ()
{
    // get modelData

    render View (modelData);
}

Votre autre option consiste à transmettre les données de modèle à partir de la page parent. Dans ce cas, vous n'avez pas besoin d'un gestionnaire d'actions et le type de modèle est identique à celui du parent:

<% Html.RenderPartial("MyControl", ViewData.Model) %>

Si votre contrôle utilisateur possède son propre type de données, vous pouvez également le construire dans la page.

Dans MyControl.ascx.cs:

public class MyControlViewData
{
    public string Name { get; set; }
    public string Email { get; set; }
}

public partial class MyControl : System.Web.Mvc.ViewUserControl <MyControlViewData>
{
}

Et dans votre page, vous pouvez initialiser le modèle de données de votre contrôle:

<% Html.RenderPartial("MyControl", new MyControlViewData ()
   {
        Name= ViewData.Model.FirstName,
        Email = ViewData.Model.Email,
   });
 %>
2
Todd Smith

Ceci est une solution qui fonctionne avec ASP.Net MVC 1.0 (beaucoup qui prétendent fonctionner avec la bêta 3 ne fonctionnent pas avec la 1.0), ne souffrent pas du problème "Le serveur ne peut pas définir le type de contenu après l'envoi des en-têtes HTTP" et peut être appelé depuis un contrôleur (pas seulement une vue):

/// <summary>
/// Render a view into a string. It's a hack, it may fail badly.
/// </summary>
/// <param name="name">Name of the view, that is, its path.</param>
/// <param name="data">Data to pass to the view, a model or something like that.</param>
/// <returns>A string with the (HTML of) view.</returns>
public static string RenderPartialToString(string controlName, object viewData) {
    ViewPage viewPage = new ViewPage() { ViewContext = new ViewContext() };
    viewPage.Url = GetBogusUrlHelper();

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

public static UrlHelper GetBogusUrlHelper() {
  var httpContext = HttpContext.Current;

  if (httpContext == null) {
    var request = new HttpRequest("/", Config.Url.ToString(), "");
    var response = new HttpResponse(new StringWriter());
    httpContext = new HttpContext(request, response);
  }

  var httpContextBase = new HttpContextWrapper(httpContext);
  var routeData = new RouteData();
  var requestContext = new RequestContext(httpContextBase, routeData);

  return new UrlHelper(requestContext);
}

C'est une méthode statique que vous pouvez abandonner à un endroit qui vous convient. Vous pouvez l'appeler de cette façon:

string view = RenderPartialToString("~/Views/Controller/AView.ascx", someModelObject); 
29
pupeno

J'ai assemblé un cadre approximatif qui vous permet de rendre des vues d'une chaîne à partir d'une méthode de contrôleur dans la version bêta de MVC. Cela devrait aider à résoudre cette limitation pour le moment.

De plus, j'ai également mis en place un framework de génération de javascript RJS de type Rails pour MVC Beta.

Découvrez-le sur http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc et dites-moi ce que vous pensez.

8
Kevin Zink

Vous devez utiliser jquery pour renseigner vos divs (et créer de nouveaux éléments HTML si nécessaire) et la sérialisation Json pour ActionResult. 

Une autre méthode consiste à utiliser jQuery pour appeler un contrôleur/une action, mais JSON utilise View (aspx ou ascx, moteur d'affichage de formulaires Web) pour le rendu du contenu. C'est à mi-chemin de UpdatePanels d'asp.net ajax ... 

J'irais probablement avec la première méthode, avec json, où vous avez un peu plus de travail à faire, mais c'est beaucoup plus "optimisé", parce que vous ne transférez pas le code HTML entier par le fil, il y a juste des objets sérialisés. C'est la façon dont les "grands" (gmail, gdocs, hotmail, ..) le font - beaucoup de code JS manipulant avec l'interface utilisateur.

Si vous n'avez pas besoin d'ajax, deux méthodes vous permettent d'appeler des vues partielles:

  • html.renderpartial ("nom d'ascx")
  • html.RenderAction (x => x.ActionName) de Microsoft.web.mvc (futures mvc)
5
Hrvoje Hudo

Après avoir beaucoup fouillé dans Google, j'ai trouvé la réponse . Vous ne pouvez pas accéder facilement au code HTML généré par la vue.

http://ayende.com/Blog/archive/2008/11/11/another-asp.net-mvc-bug-rendering-views-to-different-output-source.aspx

4
Andrew Harry

J'ai fait quelque chose de similaire pour une application sur laquelle je travaille. J'ai des vues partielles renvoyant du contenu rendu qui peut être appelé en utilisant leur chemin REST ou en utilisant:

<% Html.RenderAction("Action", "Controller"); %>

Ensuite, dans mon HTML d'affichage actuel, j'ai un fichier DIV qui est rempli à partir de jQuery:

<div class="onload">/controller/action</div>

Le jQuery ressemble à ceci:

<script type="text/javascript">
    $.ajaxSetup({ cache: false });

    $(document).ready(function () {
        $('div.onload').each(function () {
            var source = $(this).html();
            if (source != "") {
                $(this).load(source);
            }
        });
    });
</script>

Ceci recherche toutes les DIV qui correspondent à la classe "onload" et lit le chemin REST à partir de leur contenu. Il effectue ensuite un jQuery.load sur ce chemin REST et renseigne la DIV avec le résultat.

Désolé, je dois rentrer chez moi. Faites-moi savoir si vous voulez que je développe davantage.

3
Rob King

J'ai trouvé ce code d'une ligne pour fonctionner parfaitement. orderModel étant mon objet modèle. Dans mon cas, j'avais une méthode d'assistance dans laquelle je devais fusionner le code HTML d'une vue partielle.

System.Web.Mvc.Html.PartialExtensions.Partial(html, "~/Views/Orders/OrdersPartialView.cshtml", orderModel).ToString();
0
Himanshu Patel

c’est très simple il vous suffit de créer une vue partielle fortement typée (ou un contrôle utilisateur), puis dans votre logiciel de compression quelque chose comme ceci:

public PartialViewResult yourpartialviewresult()
{
    var yourModel
    return PartialView("yourPartialView", yourModel);
}

alors vous pouvez utiliser JQuery pour exécuter la requête quand vous le souhaitez:

$.ajax({
    type: 'GET',
    url: '/home/yourpartialviewresult',
    dataType: 'html', //be sure to use html dataType
    contentType: 'application/json; charset=utf-8',
    success: function(data){
         $(container).html(data);
    },
    complete: function(){ }
 });    
0
Paco Lf

Dans Rails, cela s'appelle rendre une vue partielle et vous le faites avec render :partial => 'yourfilename'. Je pense qu'ASP.NET MVC a une méthode RenderPartial similaire, mais je ne parviens pas à trouver la documentation officielle de MVC pour confirmer ou infirmer une telle chose.

0
Orion Edwards