2011-12-20 18 views
8

Estoy usando ASP .NET MVC 3 y tengo un problema interesante que resolver y espero obtener algunos consejos.¿Es posible llamar al compilador Razor mediante programación desde un método de controlador?

Tengo una página que tiene un número de divs dentro de ella. El contenido de cada div cambia con el tiempo y, por lo tanto, actualmente tengo un temporizador para cada ejecución div que hace una solicitud $ .ajax al servidor que devuelve un PartialViewResult con los contenidos actualizados del div. La vista parcial es bastante compleja y hace referencia a otras vistas.

El problema con este enfoque es que no se escala muy bien. Es posible que cada usuario tenga muchos de estos temporizadores en ejecución y que con muchos usuarios el servidor sea golpeado constantemente. Yo preferiría, por lo tanto, hacer una sola solicitud al servidor que devuelve, potencialmente, múltiples contenidos div por lo que sería:

div1 { some html } 
div2 { some html } 

...

A continuación, en el cliente podría poner cada bit de HTML en la posición correcta en la página.

Pensé que lo que podría hacer es devolver JSON desde el servidor, pero mi problema es: ¿cómo obtengo el HTML? Por el momento, el compilador razor se ejecutará y convertirá mis archivos cshtml de vista parcial en HTML, pero si devuelvo JSON, ¿es posible llamar programáticamente al compilador de afeitar?

Encontré Razor Engine aquí: http://razorengine.codeplex.com/ que parece hacer lo que quiero, pero ¿es posible hacerlo solo con vainilla ASP NET MVC?

O, dado el problema, ¿hay una mejor manera de lograr mi objetivo?

¡Gracias por cualquier ayuda!

+1

¿Por qué no crear una acción que devuelve una nueva vista parcial que representa todas las vistas parciales? De esta forma, se llama al motor desde el lugar correcto, es decir, la vista. – StuperUser

Respuesta

5

crear una acción que devuelve una nueva Vista parcial que representa todas las Vistas parciales. p. una acción:

public PartialViewResult AggregatedAction(args) 
{ 
    return PartialView(); 
} 

con una vista que contiene:

@Html.Action("IndividualAction1", null) 
@Html.Action("IndividualAction2", null) 
@Html.Action("IndividualAction3", null) 

Ver http://haacked.com/archive/2009/11/18/aspnetmvc2-render-action.aspx para más detalles.

De esta manera hay solo una solicitud y se está llamando al motor de renderizado desde el lugar correcto, es decir, la vista.

Luego, con el resultado, puede buscar los diversos divs y reemplazar el html en el cliente.

$('div#id1').html('div#id1',$(data)); 
$('div#id2').html('div#id2',$(data)); 

Si la estructura de su página lo permite, se debe utilizar: http://api.jquery.com/load/ (como dice @Jorge) para reemplazar la totalidad del html con una línea.

$('div#targetDiv').load('Controller\AggregatedAction', anyData); 
+1

Thanks StuperUser! Me tomó unos minutos darme su respuesta, pero funcionará un hechizo. Tengo un div oculto en la página que establecí como ID de objetivo para la acción de Ajax, dentro de la vista que se devuelve para la acción que hago un ciclo y pongo. cada uno de los divs que necesitan actualización y luego en Javascript los mueve al lugar correcto en la función de éxito – kmp

+1

Excelente. No debería tener que moverlos con JS en el margen de la jerarquía si están posicionados de manera diferente por CSS, por lo que puede cargar en un div "en vivo" no oculto y deben actualizarse en su posición. – StuperUser

+1

¡Buen punto, gracias! – kmp

3

Puede tener dos métodos: uno que devuelve HTML y otro que devuelve JSON.

O, alternativamente, crear un ActionResult que los delegados a una JsonResult if the request is an Ajax request, o una PartialViewResult de otra manera, por ejemplo:

public class AjaxableResult : ActionResult 
{ 

    private readonly JsonResult _jsonResult; 
    private readonly PartialViewResult _partialViewResult; 

    public AjaxableResult(JsonResult jsonResult, PartialViewResult partialViewResult) 
    { 
    _jsonResult = jsonResult; 
    _partialViewResult = _partialViewResult; 
    }  

    public override void ExecuteResult(ControllerContext context) 
    { 
    if (context.HttpContext.Request.IsAjaxRequest()) { 
     _jsonResult.ExecuteResult(context); 
    } 
    else 
    { 
     _partialViewResult.ExecuteResult(context); 
    } 
    } 
} 
+0

Muchas gracias por responder, pero mi problema es que quiero que sea una sola solicitud de AJAX para el servidor que devuelve múltiples elementos HTML para insertar, así que piense en ello como una colección de blobs HTML que luego en el cliente pongo en el lugar correcto en la página – kmp

1

¿Por qué usted acaba de hacer que Ajax llamada y en vez de esperar que un objeto JSON enviar al cliente el html con un método en el controlador de ActionResult recuerda que este tipo devolver el hTML del tipo vista como esta

//this if you want get the html by get 
public ActionResult Foo() 
{ 
    return View(); 
} 

y el cliente llamado así

$.get('your controller path', parameters to the controler , function callback) 

o

$.ajax({ 
     type: "GET", 
     url: "your controller path", 
     data: parameters to the controler 
     dataType: "html", 
     success: your function 
    }); 

también que es posible cargar vistas parciales, y hacer que en unos partes específicas de su vista con la jquery load, que no es más que una ajax llamados

+0

"carga de jquery que no es más que un ajax llamado tipo get" incorrecto. Si le pasa los datos como un objeto JavaScript, usará un POST. '" El método POST se usa si los datos se proporcionan como un objeto, de lo contrario, se asume GET ". Http://api.jquery.com/load/ – StuperUser

+0

Gracias, pero esto es como lo que estoy haciendo actualmente. Tengo un temporizador ejecutándose en el cliente que llama a un método en el controlador que recupera HTML y en el éxito lo coloca en la página. El problema es que esto significa que para cada elemento de la página que necesita actualizarse necesito hacer una solicitud de AJAX por separado – kmp

+0

Gracias, no lo sabía. Modifiqué mi respuesta – Jorge

Cuestiones relacionadas