remarks net cref c# asp.net gridview updatepanel ajax.net

c# - cref - Llamar al método.NET de forma asíncrona y vincular a la grilla al finalizar



remarks c# (2)

Container.RetrieveItems () llama a un servicio que demora un poco, por lo que me gustaría llamarlo de forma asíncrona (después de recuperar los elementos, se configuran en la propiedad Lista de la clase Container). Al finalizar la recuperación de los elementos, me gustaría actualizar un gridView que está dentro de un panel de actualización (updatePanel Mode = "Conditional" y ScriptManager EnablePartialRendering = "true". UpdatePanel no tiene elementos desencadenantes).

Establecí puntos de corte y di un paso en cada paso. Los ítems se recuperan, la cuadrícula es de datos y luego se llama actualización. No se lanzan excepciones, pero la cuadrícula no se está actualizando con el contenido. Si configuro UpdatePanel para actualizar usando un desencadenante y el evento Timer.OnTick funciona perfectamente, sin embargo, solo necesito que se actualice después de que se recuperen los elementos, por lo que activar el manual UpdatePanel.Update () al finalizar la llamada de servicio sería ideal.

He hecho bastante búsqueda, pero todas las respuestas son ''Olvidó llamar a DataBind ()''

¿Hay algo que me falta?

private void UpdateGrid() { grid.DataSource = Container.List; grid.DataBind(); updatePanel.Update(); } protected void Page_Load(object sender, EventArgs e) { var task = Task.Factory.StartNew(Container.RetrieveItems); task.ContinueWith((x) => UpdateGrid()); }

Actualización: configuré una prueba más simple para tratar de identificar el problema. Creé una etiqueta cuya propiedad Text se actualizaría al completar un método. Cuando la página cargó, llamó al método y cuando el método finalizó llamó a updatePanel.Update () pero no a cambios.

Según el consejo de Per Jaimes, intenté llamar a la actualización manual dentro de la devolución de un Button_click y efectivamente actualizó la etiqueta. Es por eso que mi configuración actual no funciona, aunque todavía estoy buscando la mejor manera de actualizar el contenido al completar una tarea asíncrona.


Jamie está en el camino correcto. Su servidor no puede "enviar" nuevos datos al cliente una vez que se haya procesado la página. El cliente debe iniciar una solicitud. Me gustaría establecer un temporizador o utilizar un JavaScript setTimeout en el cliente para sondear regularmente el servidor para ver si se completó.

Enfoque del servicio web

Otro enfoque es configurar un servicio web en el servidor, luego llamarlo desde su página. Esto se ejecutará en un nuevo hilo y actualizará la grilla de manera asíncrona tan pronto como los resultados estén disponibles.

Primero necesita configurar un servicio web de WCF. Hay miles de artículos sobre esto si no está seguro. Aquí está uno de ellos: http://www.codeproject.com/Articles/16973/Simple-Web-Service-using-WCF-Windows-Communication

Aquí hay un código de muestra de uno de mis proyectos:

namespace UI.Web.WebServices { [ServiceContract(Namespace = "WebServices")] [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] public class WebServiceName { [OperationContract] [WebInvoke(ResponseFormat = WebMessageFormat.Json)] public FacilityResult[] MethodName() { FacilityService facilityService = new return facilityService .GetAssignments()).ToArray(); } } }

Llamar al servicio web desde el cliente

A continuación, necesitará vincular la cuadrícula desde su página, usando JavaScript: http://blog.ashmind.com/2007/06/21/client-side-databinding-with-aspnet-ajax-futures/

Aquí hay un código de muestra del mismo proyecto. Este proyecto usa jQuery y JavaScript no puro como las muestras en los enlaces:

<script type="text/javascript"> function getGridData() { var payload = { }; // Put data to include here, if any $.ajax({ type: "POST", url: "/WebServiceName.svc/MethodName", data: JSON.stringify(payload), contentType: "application/json", dataType: "json", success: function (msg) { bindResultsToGrid(msg.d); }, error: function (xhr) { alert(''error'' + xhr.responseText); } }); } function bindResultsToGrid(data) { ... } </script>

Referencias http://aspalliance.com/1301_Unveil_the_Data_Binding_Architecture_inside_Microsoft_ASPNET_Ajax_10__Part_1

http://aspalliance.com/1301_Unveil_the_Data_Binding_Architecture_inside_Microsoft_ASPNET_Ajax_10__Part_2


Quería compartir mi solución completa para este problema. Si bien la respuesta de msigman fue de gran ayuda, no me ayudó a llegar hasta allí. No he encontrado una solución viable para vincular a un GridView desde el lado del cliente, así que en su lugar estoy creando la cuadrícula de javascript.

1 - Controlador de configuración para manejar la solicitud

El controlador MVC se puede llamar desde el lado del cliente a través de AJAX, lo que le permite llamar a cualquier código .NET desde el lado del cliente. Esta es una parte clave, ya que el controlador / servicio puede realizar toda la potencia y el trabajo pesado, pero aún tiene la flexibilidad de javascript. Publiqué un ejemplo completo de cómo puedes hacer esto aquí, ¿ Llamas a la función ASP.NET desde JavaScript? . (Se puede usar con Webforms o MVC).

public class TimersController : ApiController { public HttpResponseMessage<TimerDisplay[]> Get() { return new HttpResponseMessage<TimerDisplay[]>( TimerRepository.Get(), // all your .NET logic can be encapsulated here new MediaTypeHeaderValue("application/json") ); } }

2 - Iniciar la solicitud con AJAX

Esto se puede hacer en el momento en que la página se carga al incluir el evento $ (document) .ready (), al hacer clic con el botón o periódicamente con un temporizador.

$.ajax({ url: "api/timers", dataType: "json", success: function (result) { bindGrid(result); } })

3 - Enlaza los datos a una grilla

Como dije, no he encontrado una forma de enlazar datos a un GridView desde el lado del cliente. Siento que la mejor solución es usar Drop the GridView en conjunto (esto es más un control del lado del servidor y no flexible para este tipo de situación), y en su lugar puede generar la grilla desde Javascript. Si bien puede recorrer manualmente los datos y simplemente crear el <tr> y <td> usted mismo, existen bastantes frameworks grid / ui que pueden hacer esto por usted. Uno de esos marcos de interfaz de usuario que tiene un bonito objeto de cuadrícula al que puede enlazar datos JSON directamente es Kendo UI ( http://demos.kendoui.com/web/grid/index.html ) (entre muchos otros widgets útiles). Esta publicación de SO contiene más sugerencias sobre marcos de UI de JavaScript https://.com/questions/159025/jquery-grid-recommendations .

function bindGrid(gridData) { var grid = $("#grid"); grid.html(""); grid.kendoGrid({ columns: [ { field: "Place", title: "Place" }, { field: "Time", title: "Time" } ], dataSource: { data: gridData }, scrollable: false }); }