PDA

View Full Version : [CLOSED] Values in DataTable columns of type object are not rendered to json



bogc
Aug 09, 2013, 12:43 AM
Hi:

I discovered this because I need to read sql server sql_variant columns. The .net driver maps sql_variant columns to DataTable DataColumn objects of type object (typeof(object)).

The problem is that the values in these columns are not converted to json.

I attached a sample page where you can see what happens:



<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<%@ Import Namespace="Ext.Net.Calendar.Demo" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
DataTable dataTable = new DataTable("test");
dataTable.Columns.Add("Col1", typeof (int));
dataTable.Columns.Add("Col2", typeof(object));
dataTable.Rows.Add(1, "Row 1");
dataTable.Rows.Add(2, 2);
dataTable.Rows.Add(3, DateTime.Now);

Store1.DataSource = dataTable;
Store1.DataBind();
}
</script>


<!DOCTYPE html>

<html>
<head id="Head1" runat="server">
<title>GridPanel with ObjectDataSource - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />

<style>
.x-grid-cell-fullName .x-grid-cell-inner {
font-family : tahoma, verdana;
display : block;
font-weight : normal;
font-style : normal;
color : #385F95;
white-space : normal;
}

.x-grid-rowbody div {
margin : 2px 5px 20px 5px !important;
width : 99%;
color : Gray;
}

.x-grid-row-expanded td.x-grid-cell{
border-bottom-width:0px;
}
</style>


</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />



<ext:GridPanel ID="GridPanel1"
runat="server"
Title="Employees"
Frame="true"
Height="600">
<Store>
<ext:Store ID="Store1" runat="server" >
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="EmployeeID">
<Fields>
<ext:ModelField Name="Col1" Type="Int"/>
<ext:ModelField Name="Col2" Type="Auto"/>
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" DataIndex="Col1" Text="Col1" Width="150" />
<ext:Column ID="Column2" runat="server" DataIndex="Col2" Text="Col2" Width="150" />
</Columns>
</ColumnModel>
<View>
<ext:GridView ID="GridView1" runat="server">
<GetRowClass Handler="return 'x-grid-row-expanded';" />
</ext:GridView>
</View>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
</SelectionModel>
</ext:GridPanel>
</form>
</body>
</html>



The generated JavaScript code contains the data for the store coming from the DataTable object. Note that Col2 is missing from the data json object.



Ext.net.ResourceMgr.init({
id: "ResourceManager1",
aspForm: "Form1",
theme: "gray"
});
Ext.onReady(function () {
Ext.create("Ext.grid.Panel", {
store: {
model: Ext.define("App.Model1", {
extend: "Ext.data.Model",
fields: [{
name: "Col1",
type: "int"
}, {
name: "Col2"
}],
idProperty: "EmployeeID"
}),
storeId: "Store1",
autoLoad: true,
proxy: {
data: [{
"Col1": 1
}, {
"Col1": 2
}, {
"Col1": 3
}],
type: 'memory'
}
},
id: "GridPanel1",
frame: true,
height: 600,
renderTo: "App.GridPanel1_Container",
title: "Employees",
columns: {
id: "ColumnModel1",
items: [{
id: "Column1",
width: 150,
dataIndex: "Col1",
text: "Col1"
}, {
id: "Column2",
width: 150,
dataIndex: "Col2",
text: "Col2"
}]
},
selModel: window.App.RowSelectionModel1 = Ext.create("Ext.selection.RowModel", {
proxyId: "RowSelectionModel1",
selType: "rowmodel"
}),
viewConfig: {
id: "GridView1",
xtype: "gridview",
getRowClass: function (record, index, rowParams, store) {
return 'x-grid-row-expanded';
}
}
});
});


Any workaround to get all the data from the DataTable object ?

Thanks

Update: Sorry the original title of the thread doesn't make much sense. I changed it however, the forum app didn't seem to update the big title.

Baidaly
Aug 09, 2013, 3:08 AM
Hello!

You should change object to String and use Converter:


<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
<%@ Import Namespace="Ext.Net.Calendar.Demo" %>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
DataTable dataTable = new DataTable("test");
dataTable.Columns.Add("Col1", typeof (int));
dataTable.Columns.Add("Col2", typeof(string));
dataTable.Rows.Add(1, "Row 1");
dataTable.Rows.Add(2, 2);
dataTable.Rows.Add(3, DateTime.Now);

Store1.DataSource = dataTable;
Store1.DataBind();
}
</script>


<!DOCTYPE html>

<html>
<head id="Head1" runat="server">
<title>GridPanel with ObjectDataSource - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />

<style>
.x-grid-cell-fullName .x-grid-cell-inner {
font-family : tahoma, verdana;
display : block;
font-weight : normal;
font-style : normal;
color : #385F95;
white-space : normal;
}

.x-grid-rowbody div {
margin : 2px 5px 20px 5px !important;
width : 99%;
color : Gray;
}

.x-grid-row-expanded td.x-grid-cell{
border-bottom-width:0px;
}
</style>


</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" SourceFormatting="True" />

<ext:GridPanel ID="GridPanel1"
runat="server"
Title="Employees"
Frame="true"
Height="600">
<Store>
<ext:Store ID="Store1" runat="server" >
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="EmployeeID">
<Fields>
<ext:ModelField Name="Col1" Type="Int"/>
<ext:ModelField Name="Col2" Type="Auto">
<Convert Handler="
var d = Ext.Date.parse(value, 'd.m.Y H:i:s', true);
if (d != null)
return Ext.Date.format(d, 'd.m.Y');
else if (!isNaN(parseInt(value))) {
return parseInt(value);
} else {
return value;
}
"></Convert>
</ext:ModelField>
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" DataIndex="Col1" Text="Col1" Width="150" />
<ext:Column ID="Column2" runat="server" DataIndex="Col2" Text="Col2" Width="150" />
</Columns>
</ColumnModel>
<View>
<ext:GridView ID="GridView1" runat="server">
<GetRowClass Handler="return 'x-grid-row-expanded';" />
</ext:GridView>
</View>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
</SelectionModel>
</ext:GridPanel>
</form>
</body>
</html>

bogc
Aug 09, 2013, 11:26 PM
Hi:

Unfortunately I cannot follow your suggestion because, in the real case, the type of the column is set automatically by the .Net driver. And I am not in control of the stored procedure either. I think the underlying problem is that the object type columns are not rendered to JSON. Is there a way to force them to be rendered?

I also noticed that even object members of classes are not rendered either. In this example the data in Col2 is not rendered.



<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>

<%@ Import Namespace="System.Runtime.Serialization.Formatters" %>
<%@ Import Namespace="System.Xml" %>


<script runat="server">


internal class Record
{
public int Col1 { get; set; }
public object Col2 { get; set; }
}


protected void Page_Load(object sender, EventArgs e)
{

IList<Record> list = new List<Record>
{
new Record {Col1 = 1, Col2 = "Row 2"},
new Record {Col1 = 2, Col2 = 2},
new Record {Col1 = 3, Col2 = DateTime.Now},

};

Store1.DataSource = list;
Store1.DataBind();

}


</script>


<!DOCTYPE html>

<html>
<head id="Head1" runat="server">
<title>GridPanel with ObjectDataSource - Ext.NET Examples</title>
<link href="/resources/css/examples.css" rel="stylesheet" />

<style>
.x-grid-cell-fullName .x-grid-cell-inner {
font-family : tahoma, verdana;
display : block;
font-weight : normal;
font-style : normal;
color : #385F95;
white-space : normal;
}

.x-grid-rowbody div {
margin : 2px 5px 20px 5px !important;
width : 99%;
color : Gray;
}

.x-grid-row-expanded td.x-grid-cell{
border-bottom-width:0px;
}
</style>


</head>
<body>
<form id="Form1" runat="server">
<ext:ResourceManager ID="ResourceManager1" runat="server" />



<ext:GridPanel ID="GridPanel1"
runat="server"
Title="Employees"
Frame="true"
Height="600">
<Store>
<ext:Store ID="Store1" runat="server" >
<Model>
<ext:Model ID="Model1" runat="server" IDProperty="EmployeeID">
<Fields>
<ext:ModelField Name="Col1" Type="Int"/>
<ext:ModelField Name="Col2" Type="Auto"/>
</Fields>
</ext:Model>
</Model>
</ext:Store>
</Store>
<ColumnModel ID="ColumnModel1" runat="server">
<Columns>
<ext:Column ID="Column1" runat="server" DataIndex="Col1" Text="Col1" Width="150" />
<ext:Column ID="Column2" runat="server" DataIndex="Col2" Text="Col2" Width="150" />
</Columns>
</ColumnModel>
<View>
<ext:GridView ID="GridView1" runat="server">
<GetRowClass Handler="return 'x-grid-row-expanded';" />
</ext:GridView>
</View>
<SelectionModel>
<ext:RowSelectionModel ID="RowSelectionModel1" runat="server" Mode="Single" />
</SelectionModel>
</ext:GridPanel>
</form>
</body>
</html>

Thanks

Vladimir
Aug 10, 2013, 12:18 AM
Please use Type="Object" for ModelField

bogc
Aug 10, 2013, 12:25 AM
It worked in both cases!

Thanks

bogc
Aug 10, 2013, 12:38 AM
Sorry, could you please explain why this works vs using auto? I thought that auto means "use whatever data is there"...

Update: Now, I looked at my code and actually the ModelFieldType.Object has been added in 2.2. It's not in 2.1 (or maybe it was added but not in the version I am using)! I tested my sample with version 2.2.

Is there a workaround for version 2.1?

Thank you

Vladimir
Aug 10, 2013, 12:55 AM
For v2.1 please use IsComplex="true"

bogc
Aug 10, 2013, 2:17 AM
The combination Type=Auto & IsComplex = true worked.

Thanks!