Introducción
La mayoría de las veces los controles que incluye una herramienta de desarrollo puedo no cumplir con las expectativas que uno busca si quiere alcanzar una interfaz rica que aproveche toda la potencia de desarrollo, es por eso que se debe recurrir a componentes externos.
Esta situación suelo encontrarla al mostrar información en un grid, es por eso que jqGrid es un control ideal para potenciar el desarrollo de la interfaz del usuario en entorno web y además se trata de un componente de libre uso.
Lo único aspecto a tener en cuenta se relaciona con la necesidad de conocer algo de javascript, concretamente jquery y de ser posible invocación a webmethods para recuperar la información del grid.
Configuración
Para poder hacer uso de jqGrid es necesario introducir en el proyecto algunas librerías de javascript.
Las cuales pueden ser descargadas de la pagina jqGrid
La referencia a estas librerías podrían hacerse de dos formas:
- usando el tag <script> en cada una de las paginas donde se requiera el grid
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script> <script src="Scripts/jquery-ui-1.8.16.custom.min.js" type="text/javascript"></script> <script src="Scripts/jqGrid/grid.locale-es.js" type="text/javascript"></script> <script src="Scripts/jqGrid/jquery.jqGrid.min.js" type="text/javascript"></script> <link href="Scripts/jqGrid/ui.jqgrid.css" rel="stylesheet" type="text/css" />
- o usando ScriptManager.RegisterClientScriptInclude(), esto es útil cuando se quiere registrar librerías para todas las paginas de forma global, aplicándolo en el código de la Master Page
public partial class SiteMaster : System.Web.UI.MasterPage { protected override void OnInit(EventArgs e) { ScriptManager.RegisterClientScriptInclude(Page, typeof(Page), "jquery", ResolveUrl(@"~/Scripts/jquery-1.6.4.min.js")); ScriptManager.RegisterClientScriptInclude(Page, typeof(Page), "jqueryui", ResolveUrl(@"~/Scripts/jquery-ui-1.8.16.custom.min.js")); ScriptManager.RegisterClientScriptInclude(Page, typeof(Page), "json2", ResolveUrl(@"~/Scripts/json2.js")); ScriptManager.RegisterClientScriptInclude(Page, typeof(Page), "gridlocale", ResolveUrl(@"~/Scripts/jqGrid/grid.locale-es.js")); ScriptManager.RegisterClientScriptInclude(Page, typeof(Page), "jqgrid", ResolveUrl(@"~/Scripts/jqGrid/jquery.jqGrid.min.js")); base.OnInit(e); } }
Al usarse un Master Page este podría verse afectado por la rutas relativas de las paginas, lo que ocasionaría una incorrecta resolución de la url y el acceso a los archivos .js, el método ResolveUrl() nos ayuda a evitar este problema.
Definición del grid
Definir el grid con las opciones básicas no es nada difícil, para separar el código de scripting del html de la pagina facilitando así el mantenimiento verán en el ejemplo que he definido 3 .js según la operación de cada uno
En este caso en concreto, se usara el “Grid.js”, el cual define el grid maestro
$("#tbOrders").jqGrid({ datatype: 'json', colNames: ['Fecha Pedido', 'Fecha Solicitud', 'Direccion', 'Ciudad', 'Pais'], colModel: [ { name: 'OrderDate', index: 'OrderDate', width: 100, sortable: false }, { name: 'RequiredDate', index: 'RequiredDate', width: 100, sortable: false }, { name: 'ShipAddress', index: 'ShipAddress', width: 250, sortable: false }, { name: 'ShipCity', index: 'ShipCity', width: 110, sortable: false }, { name: 'ShipCountry', index: 'ShipCountry', width: 110, sortable: false } ], height: "300px", onSelectRow: function (id) { getDetailsOrderByOrder(id); } });
y un grid detalle
$("#tbDetailsOrder").jqGrid({ datatype: 'json', colNames: ['Producto', 'Cantidad', 'Precio'], colModel: [ { name: 'ProductName', index: 'ProductName', width: 250, sortable: false }, { name: 'Quantity', index: 'RequiredDate', width: 100, sortable: false }, { name: 'UnitPrice', index: 'UnitPrice', width: 100, sortable: false } ], height: "200px", width:"800px" });
La configuración es bastante estándar para un uso básico, a partir de aquí hay miles de opciones, pero básicamente se define las columnas (atributo “colNames”), así como también las propiedades de cada columnas como ser el ancho de las mismas.
En el grid maestro además se define un evento, el cual enviara el id de la entidad seleccionada para cargar así el detalle, por supuesto el id que recibe como parámetro es el valor que mas adelante veremos en la estructura json devuelta por el webmethod
Definición de los Page Métodos
El siguiente paso será definir la información en el servidor para poder recuperar los registros que cargaran el grid
Para esto se define dos Page Methods en la propia pagina web que implementa los grid (podría usarse una pagina adicional para esta definición)
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public static string GetOrdersByCustomer(string customer) { var orders = NorthwindData.GetOrdersByCustomer(customer); var grid = new { page = 1, records = orders.Count(), total = orders.Count(), rows = from item in orders let orderdate = item.OrderDate.HasValue ? item.OrderDate.Value.ToShortDateString() : "" let requireddate = item.RequiredDate.HasValue ? item.RequiredDate.Value.ToShortDateString() : "" select new { id = item.OrderID, cell = new string[]{ orderdate, requireddate, item.ShipAddress, item.ShipCity, item.ShipCountry, item.Customers.CompanyName } } }; return JsonConvert.SerializeObject(grid); }
la estructura que requiere jqGrid es un tanto especial, y gracias a los métodos anónimos es posible armarla, y como ultimo paso serializarla usando la librería JSON.NET
La estructura es bastante simple, se define la pagina, la cantidad de registros y el total, estos valores son útiles cuando el grid esta paginado, en este caso no implementamos la paginación.
Luego se definen las filas, en donde se transforma la entidad obteniendo un identidicado en el “id”, mas una propiedad “cell” que es en definitiva un array de string con la información de cada columna requiere, es importante en este punto respetar las posiciones en que debe ir cada dato con respecto a las definición de las columnas en el paso anterior.
El mismo proceso se aplica para recuperar los detalles
[WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public static string GetDetailsOrdersByOrder(int order) { var orders = NorthwindData.GetDetailsOrdersByOrder(order); var grid = new { page = 1, records = orders.Count(), total = orders.Count(), rows = from item in orders select new { id = item.OrderID, cell = new string[]{ item.ProductsReference.Value.ProductName, item.Quantity.ToString(), item.UnitPrice.ToString("N2") } } }; return JsonConvert.SerializeObject(grid); }
Invocar a los Page Methods
Los grid definidos no están conectados de forma directa para que estos invoquen los servicios de datos, sino que se definieron por separado para que uno desde código controle la invocación de los servicios.
En el archivos ServiceInvoke.js se encuentra la definición
function getOrdersByCustomer(customer) { var params = new Object(); params.customer = customer; $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", url: "Default.aspx/GetOrdersByCustomer", data: JSON.stringify(params), dataType: "json", async: false, success: function (data, textStatus) { if (textStatus == "success") { $("#tbDetailsOrder").clearGridData(); var grid = $("#tbOrders")[0]; grid.addJSONData(jQuery.parseJSON(data.d)); } }, error: function (request, status, error) { alert(jQuery.parseJSON(request.responseText).Message); } }); }
Por medio de la línea
$("#tbDetailsOrder").clearGridData();
es que se limpian los registros del grid de detalle, ya que al recargarse el principal ya no hay un registro seleccionado.
function getDetailsOrderByOrder(order) { var params = new Object(); params.order = order; $.ajax({ type: "POST", contentType: "application/json; charset=utf-8", url: "Default.aspx/GetDetailsOrdersByOrder", data: JSON.stringify(params), dataType: "json", async: false, success: function (data, textStatus) { if (textStatus == "success") { var grid = $("#tbDetailsOrder")[0]; grid.addJSONData(jQuery.parseJSON(data.d)); } }, error: function (request, status, error) { alert(jQuery.parseJSON(request.responseText).Message); } }); }
Ejemplo de Código
El ejemplo fue desarrollado con visual Studio 2008 y Sql Server 2008 R2 Express
Dentro de la carpeta “DbScript” se encuentra un .sql con la estructura de la db en caso de no poder usar el .mdf adjunto en la solución
[C#] |
Muchas gracias Leandro x el articulo, era justo lo que necesitaba para animarme a empezar a usar jqGrid.
ResponderEliminarA propósito de tu articulo y de que esta leyendo algo de información al respecto en Internet me quedan algunas dudas, como por ejemplo con éste articulo
http://codeasp.net/articles/asp-net/229/using-jqgrid-with-asp-net y si bien es cierto que la paginación y el ordenamiento funcionan correctamente, la configuración de éste ultimo requiere de bastante código(en sql server en un procedimiento almacenado se puede incluir una cadena en la clausula order by??)
O los mismo demos de jqGrid http://www.trirand.com/blog/jqgrid/jqgrid.html (Loading Data=>JSON Data) que basándome en ellos estoy tratando de acceder a los valores de "sidx" y "sord", en un WebMethod cualquiera de esta manera HttpContext.Current.Request.Form("sidx") pero aparentemente no es posible y creo que por eso optaron x usar Controlador genérico(.ashx), no sé si tendrías idea de xq no puede acceder a ésas variables desde un WebMethod pero si desde un controlador??
Gracias de antemano
hola Edalo
ResponderEliminarme parece que no puedes acceder al sidx y sord porque esta es informacion que el propio jqgrid genera cuando se renderiza en el cliente
para estar seguro cuando se carga en el browser el grid ve al codigo fuente del mismo y busca
es mas si analisas las opciones
http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options
veras que en el "prmNames" tienes esta informacion, solo sera cuestion desde jquery tomar la informacion y enviarla por parametro el webmethod
de forma automatica se enviar en la url, por eso el Request en el handler funcion, lo hace directo el jqgrid
pero al usar algo personalizado sin tratar la url debes recuperarlo previamente para poder enviarlo
podrias usar
var pageoptions = $("#grid").getGridParam("prmNames");
esto debolvera un array con todas las opciones que intervienen en la paginacion
si obtienes el sidx, puedes enviarlo en al webmethod
saludos
Buenas Leandro, al parecer ya lo tengo funcionando como quería, creo que me deje llevar de los demos del jqGrid (en php) donde los valores de "sidx" y "sord" si se pueden recuperar directamente. ¿Crees que me podrías explicar en breve que hace que un controlador genérico sí pueda tener tener acceso a ésos valores??, tampoco me queda muy claro la parte en la que señalas :"usar algo personalizado sin tratar la url"
ResponderEliminarBueno en cuanto a lo que hice para recuperar los valores de "sidx" y "sord" utilicé : $("#tbDetailsOrder").getGridParam("postData") "postData" contiene los datos necesarios para la ordenación y paginación, "prmNames" sirve para personalizar los nombres de estos valores.
En cuanto a lo de la ordenación como señalas en el articulo al no estar los grids conectados directamente,como sí sucede en el articulo donde usan un controlador genérico http://codeasp.net/articles/asp-net/229/using-jqgrid-with-asp-net, tengo que invocar manualmente el evento onSortCol http://www.trirand.com/jqgridwiki/doku.php?id=wiki:events y obviamente también modifique los WebMethods : getOrdersByCustomer y getDetailsOrderByOrder agregándole los parámetros necesarios para el ordenamiento y paginación, y eso es más o menos a grandes rasgos lo que tuve que hacer.
Otra vez muchas gracias Leandro ya hacía varios meses que quería usar jqGrid pero no encontraba un ejemplo práctico en asp.net que me sirviera como punto de inicio en el uso de este plugin y de verdad que en ese sentido tu articulo me ha caído como bajo de cielo :D literalmente
Saludos
hola
ResponderEliminarPor controlador generico te refieres a un handler ? porque si es asi recuerda que este se comporta similara a una pagina web (puede acceder al request y response) solo que se programa desde codigo (sin un diseñadro html) y se define la extension que usa en el web.config
en el articulo donde grabo imagenes en uan db los utilizo como medio para obtener estos archivos desde la db y enviarlo en el response
que bueno que con el postData pudiste recuperar esta informacion para enviar el servicios
saludos
Que onda Leandro, oye tengo una duda, fijate que no puedo visualizar al final de la funcion ajax el resultado del post del json, grid.addJSONData(jQuery.parseJSON(data.d)); exactamente ahí. le agregue un alert antes de esa linea y me regresa el siguiente valor {"ID":"1","Name":"ANGEL MARTIN"} alguna idea de ´por que el el grid no me pinte los valores?
ResponderEliminarhola Angelito
ResponderEliminarno entendi como se relaciona el final de la funcion ajax, con el alert que agregas y en el grid no pinte los valores
parecieran temas diferentes los que alli planteas, es mas por lo que comentas en el alert recibes un json de respuesta, aunque parece ser un solo item
saludos
Ok Leandro, en la funcion getOrdersByCustomer() me imagino que es donde hace la asignacion de los valores devueltos por el webmethod, pero mi grid no muestra los valores devueltos por el json le puse un alert antes de parsear (grid.addJSONData(jQuery.parseJSON(data.d); ) y me muestra lo que te mencionaba antes ( [{"ID":"1","Name":"ANGEL MARTIN"}] ), osea que por el lado del codebehind no tengo problemas. No se si me hace falta algun archivo o alguna version en especifica por las funciones de parseo.
ResponderEliminarhola Angelito
ResponderEliminarpero esto que mencionas
[{"ID":"1","Name":"ANGEL MARTIN"}]
eso es una respuesta json, o sea estas recuperando algo en formato json desde el webmethod
quizas deberias valida que este webmethod que invocas devuelve la entidad con los datos que necesitas, pero devolver un registro al menso revuelve, por eso que comentas es json
podrias poner un breakpoint en el webmethod y ver como se crea la entidad que retornas
saludos
Muy buen Blog
ResponderEliminarEs muy buena la publicacion, a mi me sirve para empezar a utilizar este control, a mi me da un poco de cacao al tratar de hacer una pagina sencilla, ya que siempre he practicado en visual basic 6 y me propuse a desarrollar una pagina de lo mas sencilla. La pregunta es si este ejemplo puedo encontrarlo en vb.net
ResponderEliminarMi agradecimiento Leandro tuttini
ResponderEliminarhola wilfred martinez garcia
ResponderEliminara veces publico articulos tanto en c# como vb.net, pero algunos por la complejidad solo los dejo en el lenguaje del cual son MVP, o sea c#
igualmente si la idea es usar este control tienes mucho de javascript, mas puntualmente jquery, por lo que vas a tener que aprender la notacion de c#, ya que javascript y c# en la notacion son similares
por lo tanto conocr vb.net, c# y javascript seguro debas hacerlo
sin olvidad html
una recomendacion si vas a ingresar al desarrollo web no seria mejor si comienzas con algo mas basico de asp.net, para aprender conceptos en lugar de arrancar con componentes jquery
saludos
Esta grilla (jqGrid)es Free?
ResponderEliminarhola sss
ResponderEliminartienes una version de libre uso (que puedes descargar y usar como lo hago en el articulo) y una de pago
pero la version licenciada se relaciona mas con el soporte que por la funcionalidad
saludos
Estimado Leandro, muy buen articulo, pero como sería con datos paginados. Quisiera saber eso, porque en el ejemplo prefijas "Page:1" y no veo la lógica para la paginación. Espero tu respuesta gracias.
ResponderEliminarhola Anthony
ResponderEliminarbueno la verdad no quise complicarlo al ejemplo por eso no pagina
jqGrid y Asp.net, un primer acercamiento
si veo de armar algun ejemplo
saludos
Estimado Leandro, y para cargar los datos al momento de cargar la página, es decir que muestre datos al cargar la página, sin necesidad de que haga click en el boton "Buscar". ?????????????
ResponderEliminarLeandro, te felicito como muchos ya lo han hecho por tu buen trabajo.
ResponderEliminarQuiero preguntarte si tienes alguna manera de que el tamaño del grid se ajuste al tamaño de la pantalla. en el ejemplo tu tienes definidos tanto el "width" como el "height". me he fijado y si se pone width:"auto", este toma el tamaño de todo el grid pero no el de la pantalla. puedes ayudarme con esto?? Muchas gracias.
hola Diego
ResponderEliminarLa verdad no me puse a evaluar el tema de layout de forma seria,
pero ya que lo planteas veo que no es tan directo, no al menos si pretendes que se adapte al movimiento del browser
Possible to make jqGrid stretch to 100%?
Resize jqGrid when browser is resized?
dale una mirada a
jqGrids.fluid extension
saludos
hola Anthony
ResponderEliminarsimplemente invocarias al metodo
getOrdersByCustomer(), en este caso sin aplicar un filtro
lo harias directo en la carga de la pagina
$(function(){
getOrdersByCustomer('');
});
recuerda que
$(function(){...
ejecutara el codigo cuando el DOM del html de la pagina se haya cargado completo, alli invocara por $.ajax y cargara el grid
saludos
disculpa, como puedo accesar al metodo OnInit? soy nuevo en c#
ResponderEliminarhola Omar Gomez
ResponderEliminaral evento OnInit del webform ?
podrias definir
protected void Page_Init(object sender, EventArgs e){
}
saludos
hola leandro, te ago una pregunta como puedo modificar datos de 5 tablas con linq to sql, cargar se cargan bien pero al momento de modificar ahi dos tablas que me fallan y no se modifican, osea cuando veo los datos en el datagrid no aparecen quedan en blancos. que podria ser.
ResponderEliminarhola luis
ResponderEliminarel tema es que al actualizar deberias tomar los datos y realziar queries de actualizacion individuales por cada tabla
o sea puedes armar una query que una todo y lo muestre
pero despues deberias tomar cada dato he impactar en cada entidad por separado, localizando cada entidad por id o codigo y pasando los cambios
saludos
Entonces Leandro...
ResponderEliminarEstoy enviando unos parametros al webmethod
$.ajax({
url:
"PaisWF.aspx/Navegar", //PageMethod
data: "{'pPageSize':'" + $('#Pais_MultiTableDatos').getGridParam("rowNum") + "','pCurrentPage':'" + $('#Pais_MultiTableDatos').getGridParam("page") + "','pSortColumn':'" + $('#Pais_MultiTableDatos').getGridParam("sortname") +
"','pSortOrder':'" + $('#Pais_MultiTableDatos').getGridParam("sortorder") +
"'}",
pero ademas quiero enviar los parametros de busqueda como searchString, searchOper, searchField.. pero no he podido dar con como los puedo enviar.... si me pudieras indicar quedaria muy agradecido.
hola CCMM
ResponderEliminarrespondi en el foro
http://social.msdn.microsoft.com/Forums/es-ES/netfxwebes/thread/bbeb2da4-8670-4608-89ab-fc57af2e47f8
Hola, he trabajado con el master detail y local funciona genial, pero cuando subo al servidor el grid maestro se ve vacío. qué podrá ser?
ResponderEliminargracias.
hola Brissa
ResponderEliminares dificil decirlo, quizas algun error que este mal controlado
podrias usar alguna tool como ser el Developer tools del IE 8 o superiore al cual accedes con la tabla F12
con este podrias hacer un Profiler de la comunicacion y ver que mensajes se envian, para validar que se reciba el json del grid
saludos
Hola leandro,
ResponderEliminarTe pregunto, cuando ejecuto la solución y escribo algo en el textbox, me sale este mensaje:
"Keyword not supported: 'password'."
PD: Estoy utilizando una inatancia local del SQL.
Gracias !
hola Cristian
ResponderEliminarque raro ese mensaje
has puesto un breakpoint en el webmethod he ingresa?
si lo hace defines un try..catch en el codigo para ver si es un problema del webmethod que falla cuando quiere recuperar la informacion
has validado el connection string que defines para conectarte a la db, si esta correcto?
saludos
Hola leandro,
ResponderEliminarGracias por responder,
Puse el breack-point, y efectivamente entra al web-metodo AutocompleteCustomer
El error ocurre en el Designer cuando se instancia este objeto:
northwindEntities context = new northwindEntities();
Mira una imagen:
https://skydrive.live.com/redir?resid=E86EA45CA85C749E!343
Referente a la cadena de conexión del .config, así me quedo:
Recuerda que ejecute el script en una instancia completa de SQL y en su efecto creé un usuario que llamé usrNorthwind, el cual tiene permisos db_owner sobre la base de datos ;)
Gracias !
Conexión:
ResponderEliminaradd name="northwindEntities" connectionString="Password=a54321;Persist Security Info=True;User ID=usrNorthwind;Initial Catalog=Northwind;Data Source=C-CPEREZ\SQL2008R2" providerName="System.Data.EntityClient"
hola Cristian
ResponderEliminarla verdad esta bastante raro el error
pero me pregunto cuando defines la invocacion a la base de northwindEntities, le pasas dos parametros si con uno solo que indique cual es la key del connection string en el config es mas que suficiente
saludos
Hola buenas gracias por la info, si alguien puede ayudarme estoy teniendo problemas para pagina una grilla en C# con webservice. el funcionamiento es el siguiente
ResponderEliminaral cargar la pagina se carga la grilla.
luego por medio de un webservice ( no editando desde la grilla) modifico el dato en la BD, el tema es que cuando me devuelve el ok del webservice de dato modificado, no puedo refrescar la grilla sin que mantenga el paginado .
hay algun ejemplo que cumpla con esto?
muchas gracias
hola Maximiliano
ResponderEliminarcuando mencionas grilla es que usas el jqGrid, o se trata del GridView de asp.net ?
porque se supone que al actualizar deberias enviar el nro de la pagina en que te encuentras para recuperar los datos de esta puntualmente
el webmethod que uses para recuperar la info del grid seguro tiene entre sus parametro el nro pagina que quiere recuperar, ese valor debes asignarlo con el que tienes actualmente
veras que cuando informo devuelvo los datos del page, records y total, en este caso no tengo paginado pero si lo tuviera alli informaria los datos de que pagina se esta mostrando
podrias analizar
jqGrid y Asp.net, un primer acercamiento
analiza la definicion de de los parametros del webmethod
saludos
necesito rellenar un campo de texto al seleccionar un elementod e mi jqgrid pero nose como hacerlo..
ResponderEliminarhola Natalia
ResponderEliminarquizas esto ayude
Cell Editing
lo que veo es que en la definicion de la columan debes poner
editable:true, edittype:'text'
para habilitar que esa columan es editable
saludos
Hola leandro, estoy haciendo un proyecto y se me ha presentado un inconveniente.
ResponderEliminarCodigo
public string getEventosUsuario(string email2)
{
int IdUsuario = usuario.getIdUser(email2);
List lista = (from eventosUsuario in context.userEvents
where eventosUsuario.Id_usuario == IdUsuario
select eventosUsuario.Id_evento).ToList();
var eventos = context.Events;
var grid = new
{
page = 1,
records = eventos.Count(),
total = eventos.Count(),
rows = from item in eventos
where lista.Contains(item.Id)
select new
{
id = item.Id,
cell = new string[]{
item.nombre,
item.fecha_ini.ToString(),
item.fecha_fin.ToString(),
item.descripcion
}
}
};
return Newtonsoft.Json.JsonConvert.SerializeObject(grid);
//var cadena = new JavaScriptSerializer().Serialize(grid);
//return cadena;
//string cadena = Newtonsoft.Json.JsonConvert.SerializeObject(records); --Tambien funciona :D
}
Error : LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
Agradezco su colaboración
Implemente el ejemplo y al cargar la pagina me deshabilita todo el contenido, como si estuviera en una capa inferior, lo movi a otra pagina y me sucede los mismo... no se donde esta el error...
ResponderEliminarhola Sombrerete
ResponderEliminarrecuerda que cuando usas entity framework todo el link que armes se traduce a un sql
por lo tanto cuando usas
var eventos = context.Events;
no se ejecua ninguna linq, recien lo hace cuando
rows = from item in eventos ...
es raro que no dijo nada del Contains() porque tampoco es soportado, pero donde falla es al hacer
item.fecha_ini.ToString(),
quizas debas usar
var eventos = context.Events.ToList();
esto fuera a traer a memoria todos los eventos, asi depsues usarias linq to object para armar las rows
saludos
Error al tratar de serializar la cadena grid, sucede cuando coloco los campos tipo fecha y los quiero pasar a String,
ResponderEliminarsi quito estos dos campos funciona correctamente
public string getEventosUsuario(string email2)
{
int IdUsuario = usuario.getIdUser(email2);
var eventos = context.Events;
var grid = new
{
page = 1,
records = eventos.Count(),
total = eventos.Count(),
rows = from items in eventos
where (from eventosUsuario in context.userEvents
where eventosUsuario.Id_usuario == IdUsuario
select eventosUsuario.Id_evento).Contains(items.Id)
select new
{
id = items.Id,
cell = new List(){
items.nombre,
items.descripcion,
items.fecha_ini.ToString(),
items.fecha_ini.ToString()
}
}
};
var cadena2 = Newtonsoft.Json.JsonConvert.SerializeObject(grid);
return cadena2;
}
Error: LINQ to Entities does not recognize the method 'System.String ToString()' method, and this method cannot be translated into a store expression.
Lo intente hacer de esta otra forma y tampoco funciono
var grid2 = new
{
page = 1,
records = eventos.Count(),
total = eventos.Count(),
rows = (from items in eventos
where (from eventosUsuario in context.userEvents
where eventosUsuario.Id_usuario == IdUsuario
select eventosUsuario.Id_evento).Contains(items.Id)
select items).Select(o => new
{
id = o.Id,
cell = new List(){
o.nombre,
o.fecha_ini.Value.ToString(),
o.fecha_fin.Value.ToString(),
o.descripcion
}
})
};
hola william
ResponderEliminarrecuerda que al usar entity framework las queries de linq que definas se traducen a sql para eejcutarse contra la db, por lo tanto no puedes usar metodo de .net que no se puedan convertir a una expression sql
eso es justamente lo que menciona el error, el ToString(), que usas aqui
o.fecha_ini.Value.ToString(),
no puede usarlo
saludos
Muchas gracias leandro por tu colaboración. Este es el código con el que resolvi el problema :D
ResponderEliminarpublic string getEventosUsuario(string email2)
{
int IdUsuario = usuario.getIdUser(email2);
var eventos = context.Events;
var grid = new
{
page = 1,
records = eventos.Count(),
total = eventos.Count(),
rows = from items in eventos.ToList()
where (from eventosUsuario in context.userEvents
where eventosUsuario.Id_usuario == IdUsuario
select eventosUsuario.Id_evento).Contains(items.Id)
select new
{
id = items.Id,
cell = new List(){
items.nombre,
items.descripcion,
items.fecha_ini.ToString(),
items.fecha_fin.ToString(),
}
}
};
var cadena2 = Newtonsoft.Json.JsonConvert.SerializeObject(grid);
return cadena2;
}
hola william
ResponderEliminarojo que cuando haces
eventos.ToList()
estas trayendo la tabla completa a memoria, si son pocos registros no tendras problemas pero si la tabla crece, bueno no creo que sea performante
saludos
Hola Leandro, primero felicitaciones por tu blog y seguido a esto queria me des tu opinion sobre como cargar los select de la grilla, ejemplo, segun JQGRID el formato para armar un select debe ser pasado de esta forma Ej. editoptions: { value: “FE:FedEx; IN:InTime; TN:TNT” } y con esta cadena se armaria el select, bien, yo encontre una solucion (no muy elegante) para devolver este formato desde un WebMethod y es la siguiente:
ResponderEliminarStringBuilder sb = new StringBuilder();
sb.Append(":;");
foreach (var el in RolBLL.ListRol())
{
sb.Append(el.ID_Rol);
sb.Append(":");
sb.Append(el.Rol);
sb.Append(";");
}
return sb.ToString();
queria me des tu opinion y saber si conoces alguna otra forma utilizando, por ejemplo, alguna propiedad de JsonConvert que devuleva este formato, gracias! y saludos
hola Gaston
ResponderEliminarpero porque no creaste el objeto usando un entidad anonima y luego la serialzias con json.net
como lo realizo en este articulo, queda en el codigo mucho mejro que armar algo como string
saludos
//Hola Leandro buenas noches y feliz año; como veras aun sigo quebrandome la cabeza porque no puedo llenar mi jqgrid!!
ResponderEliminar//tengo 2 proyectos
//-Datos(DataAccess)
//-Vista(Forms and WebService)
//Mi codigo en C#:
//-Datos
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Datos
{
public class Orders
{
public string Id { get; set; }
public string Name { get; set; }
public string OrderDate { get; set; }
public string Employee { get; set; }
}
}
//************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace Datos
{
public class Functions
{
SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["conex"].ConnectionString);
public List d_GetOrders()
{
List list = new List();
Orders entity;
string sql = "select OrderID Id,ContactName Name,OrderDate,(FirstName + ' ' + LastName) Employee " +
"from (Orders o inner join Customers c on o.CustomerID=c.CustomerID) " +
"inner join Employees e on o.EmployeeID=e.EmployeeID";
SqlCommand cmd = new SqlCommand(sql, cn);
cmd.CommandType = CommandType.Text;
cn.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
entity = new Orders();
entity.Id = dr[0].ToString();
entity.Name = dr[1].ToString();
entity.OrderDate = dr[2].ToString();
entity.Employee = dr[3].ToString();
list.Add(entity);
}
cn.Close();
return list;
}
}
}
//***********************************************
//-WebService
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
using System.Web.Script.Serialization;
using Datos;
using System.Web.Script.Services;
using Newtonsoft.Json;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService {
public WebService () {
//InitializeComponent();
}
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string WSGetOrders() {
Functions obj = new Functions();
var grid = obj.d_GetOrders();
var griddata = new
{
total ="1",
page = "1",
records = "10",
rows= grid
};
return JsonConvert.SerializeObject(griddata);
}
}
//*****************************************************
//Mi pregunta esta en 2 partes porque el blogger no me permitia !!
ResponderEliminar//**********************************************
//-ASPX
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Prueba JQGRID</title>
<link href="css/jquery-ui-1.9.1.custom.min.css" rel="stylesheet" type="text/css" />
<link href="css/ui.jqgrid.css" rel="stylesheet" type="text/css" />
<script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="js/grid.locale-es.js" type="text/javascript"></script>
<script src="js/jquery.jqGrid.min.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.9.1.custom.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#list").jqGrid({
url: "WebService.asmx/WSGetOrders",
contenttype: "application/json; charset=utf-8",
datatype: "json",
data: "{}",
height: 250,
colNames: ['Id', 'Name', 'OrderDate', 'Employee'],
colModel: [
{ name: 'Id', index: 'Id', width: 60 },
{ name: 'Name', index: 'Name', width: 90 },
{ name: 'OrderDate', index: 'OrderDate', width: 100 },
{ name: 'Employee', index: 'Employee', width: 100 }
],
caption: "ORDERS",
altRows: true
});
});
</script>
</head>
<body>
<table id="list"></table>
<div id="page"></div>
</body>
</html>
//******************************************************
//Algunos valores devueltos de json son (mediante un alert lo comprobe):
{
"total": "1",
"page": "1",
"records": "10",
"rows": [
{
"Id": "10248",
"Name": "Paul Henriot",
"OrderDate": "04/07/1996 12:00:00 a.m.",
"Employee": "Steven Buchanan"
},
{
"Id": "10249",
"Name": "Karin Josephs",
"OrderDate": "05/07/1996 12:00:00 a.m.",
"Employee": "Michael Suyama"
},
{
"Id": "10250",
"Name": "Mario Pontes",
"OrderDate": "08/07/1996 12:00:00 a.m.",
"Employee": "Margaret Peacock"
},
{
"Id": "10251",
"Name": "Mary Saveley",
"OrderDate": "08/07/1996 12:00:00 a.m.",
"Employee": "Janet Leverling"
},
{
"Id": "10252",
"Name": "Pascale Cartrain",
"OrderDate": "09/07/1996 12:00:00 a.m.",
"Employee": "Margaret Peacock"
}
]
}
//********************************************************
//pero mi grdi sigue vacio
//Mil gracias por la atencion!!!
hola Franky
ResponderEliminarlo que noto es que el web service devuelve el json como string, pero no pones el codigo el evento "success" dodne la linea importante es:
grid.addJSONData(jQuery.parseJSON(data.d));
con es alinea estarias asignando el contenido, porque no cargas el grid usando $.ajax u no directo la url en el jqgrid
es que sino el webservice deberia devolver json de forma directa y no un string
saludos
Leandro intente con otro metodo en el cual si los datos estan escritos directamente en el <script> como:
ResponderEliminarcadena = [
{ "codigo": "1A", "fecha": "31-07-2014", "nombre": "test", "total": "210.00" },
{ "codigo": "2A", "fecha": "2007-10-02", "nombre": "test2", "total": "320.00" },
{ "codigo": "3A", "fecha": "2007-09-01", "nombre": "test3", "total": "430.00" }
];
Luego
$("#list").jqGrid({
datatype: "local",
data: cadena,.........
Cargan los datos perfectamente; ahora lo que intente hacer es devolver un string desde webmethod:
[{"codigo":"10258","fecha":"17-07-1996","nombre":"Roland Mendel","total":"10"},{"codigo":"10270","fecha":"01-08-1996","nombre":"Pirkko Koskitalo","total":"10"},{"codigo":"10275","fecha":"07-08-1996","nombre":"Giovanni Rovelli","total":"10"},{"codigo":"10285","fecha":"20-08-1996","nombre":"Horst Kloss","total":"10"},{"codigo":"10292","fecha":"28-08-1996","nombre":"Anabela Domingues","total":"10"}];
Y en una funcion generada me esta devolviendo correctamente en string:
var cadena;
$.ajax(
{
type: "POST",
url: "WebService.asmx/ObtenerPedidos",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
cadena = response.d;
alert(cadena);
},
error: function (result) {
alert('ERROR ' + result.status + ' ' + result.statusText);
}
});
Ahora como haria para pasar ese string como los valores del jqgrid, gracias.
hola Franky
ResponderEliminartiene que usar el
grid.addJSONData(jQuery.parseJSON(data.d));
para pasar ese jason al grid
saludos
Hola Leandro,
ResponderEliminaryo estoy usando jqgrid con php y sql server 2008,
pero como puedo realizar busquedas por fechas y que muestren en una grilla.
Hola Leandro,
ResponderEliminaryo estoy usando jqgrid con php y sql server 2008,
pero como puedo realizar busquedas por fechas y que muestren en una grilla.
hola Michael
ResponderEliminarla verdad ninca programe con PHP
imagino que debe tener librerias para poder conectarte a la db y ejecutar una query
pero no estoy seguro como se lo enviarias al jqgrid, quizas podrias hacer una pagina php que se conecte a la db y devuelva el json, y esta pagina la usas en la url del jqgrid
saludos
Muchas Gracias,
ResponderEliminarBuenas tardes leandro acudo a ti como ultimo recurso jajajaja disculpaaaaaaaa mi duda es la siguiente yo lleno mi jqgrid dependiendo de la opcion que seleccionan en un select, el problema es que el grid solo se carga la primera vez que selecciono una opcion, la segunda ya no se actualiza con los nuevos datos que escogio el usuario
ResponderEliminartengo el armado de mi jqgrid asi mira:
function CreaGrid(datos) {
$(function () {
var grid = jQuery('#GridProve');
grid.jqGrid({
data: jQuery.parseJSON(datos),
datatype: 'local',
height: 200,
hidegrid: false,
rowNum: 10,
viewrecords: true,
caption: 'Proveedores',
pager: '#pager',
colNames: ['ID', 'Proveedor', 'Convenio'],
colModel: [
{ name: 'IDProve', index: 'IDProve', width: 100, align: 'center', sorttype: 'int', hidden: true },
{ name: 'StrNombreProve', index: 'StrNombreProve', width: 200, align: 'left', sorttype: 'int' },
{ name: 'BooConvenio', index: 'BooConvenio', width: 100, align: 'center', formatter: 'checkbox', stype: 'select', searchoptions: { sopt: ['eq'], value: ':Todos;true:Con Convenio;false:Sin Convenio'} }
],
onSelectRow: function (id) {
ObtenerDetalleProveedor(id);
}
});
grid.jqGrid('filterToolbar', { stringResult: true, searchOnEnter: false, defaultSearch: 'cn' });
});
el select llama al webmethod mediante ajax y le regresa al ajax el json si el resultado es success mando a llamar a la funcion que te coloque arriba, la variable datos es la que me trae el nuevo json para cargar los nuevos datos, pero no se actualiza, que estoy haciendo mal de antemano muchas gracias..
ya encontre la solucion seeeeeeee!!!
ResponderEliminarMe quedo asi
//lIMPIA LOS REGISTROS ANTERIORES
$("#GridProve").clearGridData();
//ASIGNA LOS NUEVOS DATOS AL JGGRID
$('#GridProve').setGridParam({ data: jQuery.parseJSON(datos) }).trigger('reloadGrid');
desconocia que tenia que hacer esto para asignar nuevos dantos creia yo que al crear el grid la variable jalaria siempre los datos del constructor pero no es asi con el metodo 'setGridParam' agregas los nuevos datos y como tu bien mencionas arriba el metodo clearGridData limpia los anteriores..
De ante mano muchas gracias ya estaba desesperado con esta cosa pero al fin ya quedoo espero y les sirva a las personas que este haciendo lo mismo que yo saludos...
como obtener los valores del Tag
ResponderEliminaren un treeview?
lleno el treeview y en cada nodo con CapaEntidades.Clientes=new CapaEntidades.Clientes();
Clientes.IdCliente=1;
MiNodo.Tag=Clientes;
hola Jose
ResponderEliminarno entendi, a que treeview haces referencia?
este articulo trata sobre jqgrid
saludos
Buenas, lo primero muchas gracias por el post.
ResponderEliminarMi duda trata sobre la conversión de un dataSet a Json en .net , pero siendo este Json válido para utilizarlo con Jqgrid.
Gracias, un saludo!
hola
Eliminarno creo que sea buena idea convertir un dataset a json, quizas deberias convertir los datos a una clase que tu definas como entidad, y usar un List<>
entonces esta lista si puedes serializarla a json usando json.net
saludos