2011-04-10 26 views
18

Estoy tratando de actualizar this tutorial para implementar Facebook BigPipe a navaja.ASP.Net MVC 3 Razor Response.Write position

Hay una extensión html helper que agrega un pagelet a una lista y luego genera un div titular a la respuesta. La idea es que, más adelante, el contenido de esta página se represente a una cadena y luego se inyecte en esta división div mediante javascript.

public static void RegisterPagelet(this HtmlHelper helper, Pagelet pagelet) { 
    var context = helper.ViewContext.HttpContext; 
    List<Pagelet> pagelets = (List<Pagelet>)context.Items["Pagelets"]; 
    if (pagelets == null) { 
     pagelets = new List<Pagelet>(); 
     context.Items["Pagelets"] = pagelets; 
    } 
    pagelets.Add(pagelet); 
    context.Response.Write("<div id=\"" + pagelet.Container + "\"></div>"); 
} 

En el ejemplo de esta función se llama así:

<div id="textHolder"> 
    <% Html.RegisterPagelet(myPagelet); %> 
</div> 

que añade el pagelet a las listas, y da salida a la div de retención a la secuencia de respuesta.

Así

<div id="textHolder"> 
    <div id="pageletPlaceHolder"></div> 
</div> 

Sin embargo, cuando trato igual en la maquinilla de afeitar:

<div id="textHolder"> 
    @{ Html.RegisterPagelet(myPagelet); } 
</div> 

El div indicador de posición aparece en la parte superior del cuerpo, fuera del div textHolder. ¿Por qué es esto? ¿Cómo puedo hacer que esto se comporte como la vista de formas web donde se genera la respuesta dentro del div?

Gracias.

Respuesta

40

vista Una maquinilla de afeitar se hace de dentro a fuera. Básicamente, escribe contenido en búferes temporales que se escriben en la secuencia de respuesta cuando se alcanza la página de diseño más alta. Por lo tanto, al escribir directamente en la secuencia de respuesta de su extensión HtmlHelper, se generará un error.

La solución es utilizar:

helper.ViewContext.Writer.Write("<div id=\"" + pagelet.Container + "\"></div>"); 
+0

¡Genial! Eso funciono. Gracias. – Terry

+2

Gracias, arreglaron un poco la cabeza rascándose allí :) – MemeDeveloper

+2

Terry ¿lo intentó @ Html.Raw? –

-4

No me molestaría en hacerlo. El resultado final que desea es t tener FooBar escrito dentro de su div, entonces ¿por qué no simplemente escribirlo en su div? ¿Por qué necesita usar Response.Write?

+0

vi un tutorial sobre el uso Pagelets (término Facebooks para servir páginas en trozos que son procesadas en el lado del servidor paralelo) y yo estoy tratando de actualizarlo a la afeitadora. La función real de ayudante pasa un pagelet y la agrega a una lista almacenada en el contexto http. Después de que el pagelet se haya agregado a esta lista, necesito generar un skeleton div, en el que pueda insertar el contenido más tarde. Por lo tanto, uso la respuesta.escribir en lugar de devolver una cadena. – Terry

+1

Porque hay momentos en los que es completamente válido para poder escribir en la secuencia de salida de forma explícita. – Craig

0

Debería usar ViewBag y poner la cadena allí, luego emitirla.

En el regulador:

ViewBag.Foo = Bar; 

En vista:

<div> 
@ViewBag.Foo 
</div> 
4

cambiar su método a ser no nulo, pero volviendo MvcHtmlString

public static MvcHtmlString OutputText(this HtmlHelper helper, string text) { 
    return New MvcHtmlString(text); 
} 

que el uso de este como antes

<div id="textHolder"> 
    @Html.OutputText("FooBar"); 
</div> 

idea es inspirado por el hecho de que casi todos los de entrada (y otros) método de extensión en MVC devuelve MvcHtmlString

+0

Acabo de actualizar la pregunta para aclarar un poco lo que estoy tratando de hacer. No quería ir por esta ruta porque, si bien funcionará para este marcador de posición inicial, más adelante en la solicitud procesaré el contenido de este marcador de posición y quiero enviarlo a la respuesta. No quiero devolver una cadena porque es posible que sea una cadena muy grande y me preocupaba el rendimiento. – Terry

+0

Cadena se crea de todos modos :). Puede separar la lógica de creación de cadenas de destino y su lógica de uso. La lógica de uso puede ser dos métodos, primero para escribir cadena generada directamente en el flujo de respuesta y otra para crear MvcHtmlString para el uso de la afeitadora. Además, de otra manera, podría crear una vista parcial para Pagelet. Que puede ser utilizado por otras vistas de la maquinilla de afeitar y también escrito directamente en la respuesta – archil

+0

Después de llamar al ayudante RegisterPagelet, al final de mi vista de diseño llamo a otra función llamada ExecutePagelet. Esto hace un ciclo paralelo sobre las páginas, renderizando cada una, luego escribiéndola en la respuesta y descargándola. No creo que una cadena me ayude allí. ¿Es el hecho de que la escritura de respuesta se comporta de manera diferente en razor a bug? – Terry