2008-11-13 27 views
27

He desarrollado un mecanismo simple para que mi sitio web mvc extraiga html a través de jquery, que luego rellena un div especificado. Todo está bien y parece genial.
Mi problema es que ahora estoy creando código HTML dentro de mi controlador (lo cual es muy fácil de hacer en VB.net por cierto) Prefiero no mezclar la separación de preocupaciones.Obteniendo el HTML de una vista parcial desde el interior del controlador

¿Es posible utilizar un "Control de usuario de MVC View" personalizado para satisfacer esta necesidad? ¿Puedo crear una instancia de control, pasar los datos del modelo y renderizar a html? Entonces sería una simple cuestión de renderizar y pasar de nuevo al navegador que llama.

+1

¿No estás mezclando la separación de preocupaciones haciendo marcas HTML en tu controlador de todos modos? Si necesita hacer algo repetidamente, mire con un control ascx? –

+0

¿No debería preocupar a la vista la generación de HTML? ¿Por qué está marcado en su controlador? –

+0

http://2leggedspider.wordpress.com/2009/11/05/serializing-a-partialview-as-json-in-asp-net-mvc/ solo necesitaba la misma funcionalidad. volviendo parcial prestado en mi objeto Json. Este enlace fue útil para mí – Bcelik

Respuesta

2

Tiene varias opciones.

Cree un controlador de acción y control de usuario de MVC View en su controlador para la vista. Para renderizar la vista utilice

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

En este caso, el gestor de acción tendrá que pasar los datos del modelo a la vista

public ActionResult MyControl() 
{ 
    // get modelData 

    render View (modelData); 
} 

Su otra opción es pasar los datos del modelo de la página principal. En este caso no es necesario un controlador de la acción y el tipo de modelo es el mismo que el de los padres:

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

Si el control de usuario tiene su propio tipo de datos también se puede construir dentro de la página

En 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> 
{ 
} 

Y en su página, puede inicializar el modelo de datos de tu control:

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

esto no le da acceso programático al HTML generado por la vista/parcial ¿no? No entiendo cómo responde esto a la pregunta ... aunque sí aprendí de la respuesta, así que lo valoro como una respuesta de alta calidad. –

+3

Esta respuesta no responde la pregunta. ¿Cómo obtengo el HTML de una vista parcial desde el interior del controlador? –

+0

¿Quieres capturar/modificar el código HTML antes de enviarlo al navegador? –

0

En los rieles esto se denomina hacer una vista parcial, y lo haces con render :partial => 'yourfilename'. Creo que ASP.NET MVC tiene un método similar de RenderPartial, pero no puedo encontrar los documentos oficiales de MVC para confirmar o denegar tal cosa.

+0

He estado buscando en Google este problema; parece que hay algunos métodos que se han roto/eliminado desde que MVC pasó a beta. Sigue buscando una respuesta –

7

Se podría crear su acción como esta:

 public PartialViewResult LoginForm() 
     { 
      var model = // get model data from somewhere 
      return PartialView(model); 
     }

Y la acción devolvería la vista parcial prestado a su respuesta jQuery.

Su jQuery podría ser algo como esto:

$('#targetdiv').load('/MyController/LoginForm',function(){alert('complete!');});
5

Debe utilizar jQuery para poblar su divs (y crear nuevos elementos HTML si es necesario), y la serialización JSON para ActionResult.

Otra forma es usar jquery para llamar a algún controlador/acción, pero en su lugar json usar vista normal (aspx o ascx, webforms ver motor) para representar contenido, y con jquery solo inyectar ese html a algún div. Esto está a medio camino de UpdatePanels de asp.net ajax ...

Probablemente vaya con el primer método, con json, donde tienes poco más trabajo que hacer, pero está mucho más "optimizado", porque no lo haces Para transferir html completo por el cable, solo hay objetos serializados. Es la forma en que los "grandes" (gmail, g docs, hotmail, ...) lo hacen: gran cantidad de código JS que se manipula con UI.

Si usted no necesita ajax, a continuación, usted tiene básicamente dos formas de llamar vistas parciales:

  • Html.RenderPartial ("nombre de ascx")
  • html.RenderAction (x => x .ActionName) de Microsoft.web.mvc (mvc futuros)
+0

En el primer método que sugirió, ¿se refiere a usar vistas parciales? –

+0

No, no hay una vista para mostrar el contenido, al menos no en el lado del servidor, solo el objeto Json que se devuelve a jQuery, que luego debe realizar la representación: crear dinámicamente divisiones, intervalos, tablas ... y completarlas con datos de json ajax solicitud. El segundo método representa HTML completo en el servidor y lo devuelve al cliente. –

8

Armado un marco aproximado que le permite representar vistas en una cadena desde un método de controlador en MVC Beta. Esto debería ayudar a resolver esta limitación por ahora.

Además, también armé un marco de generación de JavaScript RJS similar a Rails para MVC Beta.

Échale un vistazo al http://www.brightmix.com/blog/how-to-renderpartial-to-string-in-asp-net-mvc y déjame saber lo que piensas.

29

Esta es una solución que está funcionando con ASP.Net MVC 1.0 (muchos que afirman que funciona con beta 3 no funciona con 1.0), no sufre del 'Servidor no puede establecer el tipo de contenido después de que se hayan enviado encabezados HTTP 'problema y se puede llamar desde el interior de un controlador (no sólo una vista):

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

es un método estático que puede caer en algún lugar que les resulta conveniente. Puede llamarlo de esta forma:

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

Esto todavía es algo que se necesita con frecuencia en cualquier proyecto importante de MVC. Así que gracias por el método –

+0

Esto no parece funcionar para mí porque mis parciales hacen uso de la clase UrlHelper metida en la propiedad Url del ViewUserControl, y este método parece dejar esa propiedad nula, lo que resulta en Excepciones en mis llamadas de ayuda . ¿Algún consejo? –

+0

Michael, tal vez alguna información en http://stackoverflow.com/questions/2031995/call-urlhelper-in-models-in-asp-net-mvc puede ayudarlo. No recuerdo haber tenido problemas con Url y creo que lo estaba usando. – Pablo

3

He hecho algo similar para una aplicación en la que estoy trabajando. Tengo vistas parciales que regresan contenido representado puede ser llamado usando su camino REST o el uso de:

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

Luego, en mi HTML con la imagen real que tienen un DIV que está lleno de jQuery:

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

Las miradas jQuery de esta manera:

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

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

este Busca todos los DIV que coincidan con la clase "onload" y lee la ruta de reposo de sus contenidos. Luego hace una jQuery.load en esa ruta REST y rellena el DIV con el resultado.

Lo siento, tengo que ir a buscar mi casa. Avísame si quieres que elabore más.

+0

. simplemente impresionante – ekkis

0

es muy sencillo sólo hay que crear un establecimiento inflexible vista (o control de usuario) parcial continuación en su cotroller algo como esto:

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

entonces se puede usar jQuery para realizar la solicitud whener desea :

$.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

Encontré que este código de una línea funcionaba perfectamente. orderModel es mi objeto modelo. En mi caso, tenía un método de ayuda en el que tenía que fusionar un html de vista parcial.

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