Ordinamento dei dati con i controlli origine dati
Aggiornamento: novembre 2007
È possibile visualizzare i dati in una pagina Web ASP.NET utilizzando un controllo origine dati e un controllo con associazione a dati. Alcuni controlli dati consentono agli utenti di ordinare i dati senza necessità di codice.
Se si desidera consentire agli utenti di ordinare i dati in fase di esecuzione, è possibile utilizzare un controllo LinqDataSource, ObjectDataSource, SqlDataSource o AccessDataSource come controllo origine dati. Per visualizzare i dati che gli utenti possono ordinare, è possibile utilizzare un controllo GridView o un controllo ListView.
Creazione di un'interfaccia utente per l'ordinamento
È possibile creare un'interfaccia utente per l'ordinamento. Tuttavia, i controlli GridView e ListView forniscono un ordinamento predefinito per l'interfaccia utente.
Il controllo GridView supporta l'ordinamento per singola colonna senza richiedere alcuna attività di programmazione. Si imposta la proprietà AllowSorting su true per creare automaticamente il testo dell'intestazione per ogni colonna come pulsante di collegamento che passa un'espressione di ordinamento al controllo origine dati. Le funzionalità di ordinamento del controllo GridView possono essere ulteriormente personalizzate mediante la gestione dell'evento di ordinamento. Per ulteriori informazioni, vedere Ordinamento dei dati in un controllo server Web GridView.
È possibile ordinare i dati visualizzati in un controllo ListView aggiungendo un pulsante al modello LayoutTemplate del controllo e impostando la proprietà CommandName del pulsante su "Sort". La proprietà CommandArgument del pulsante viene impostata sul nome della colonna in base alla quale eseguire l'ordinamento. Facendo clic sul pulsante Sort si passa dall'ordinamento Ascending all'ordinamento Descending e viceversa. Per ulteriori informazioni, vedere Cenni preliminari sul controllo server Web ListView e Procedura dettagliata: visualizzazione, paging e ordinamento di dati tramite il controllo server Web ListView.
Attivazione dell'ordinamento in un controllo origine dati
I controlli origine dati che forniscono il supporto incorporato per l'ordinamento sono LinqDataSource, ObjectDataSource, SqlDataSource e AccessDataSource. Il controllo LinqDataSource supporta l'ordinamento quando la proprietà AutoSort è impostata su true, ovvero sull'impostazione predefinita, come nell'esempio seguente:
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Products"
AutoPage="true"
AutoSort="true"
ID="LinqDataSource1"
>
</asp:LinqDataSource>
<asp:GridView
AllowPaging="true"
AllowSorting="true"
DataSourceID="LinqDataSource1"
ID="GridView1"
>
</asp:GridView>
<asp:LinqDataSource
ContextTypeName="ExampleDataContext"
TableName="Products"
AutoPage="true"
AutoSort="true"
ID="LinqDataSource1"
>
</asp:LinqDataSource>
<asp:GridView
AllowPaging="true"
AllowSorting="true"
DataSourceID="LinqDataSource1"
ID="GridView1"
>
</asp:GridView>
I controlli SqlDataSource e AccessDataSource supportano l'ordinamento solo se la rispettiva proprietà DataSourceMode è impostata su DataSet, ovvero sull'impostazione predefinita, come nell'esempio seguente:
<asp:GridView ID="EmployeesGridView"
DataSourceID="EmployeesSqlDataSource"
DataKeyNames="EmployeeID"
AllowSorting="True"
RunAt="Server" />
<asp:SqlDataSource ID="EmployeesSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees"
Connectionstring="<%$ ConnectionStrings:NorthwindConnectionString %>"
RunAt="server" />
<asp:GridView ID="EmployeesGridView"
DataSourceID="EmployeesSqlDataSource"
DataKeyNames="EmployeeID"
AllowSorting="True"
RunAt="Server" />
<asp:SqlDataSource ID="EmployeesSqlDataSource"
SelectCommand="SELECT EmployeeID, LastName, FirstName FROM Employees"
Connectionstring="<%$ ConnectionStrings:NorthwindConnectionString %>"
RunAt="server" />
Il controllo ObjectDataSource supporta l'ordinamento se l'oggetto restituito da SelectMethod è un oggetto DataSet, DataTable o DataView. ObjectDataSource supporta inoltre il recupero dei risultati dell'origine dati con un criterio di ordinamento.
Ordinamento personalizzato
È possibile personalizzare la modalità di esecuzione dell'ordinamento da parte dei controlli con associazione a dati e dei controlli origine dati. Ciò consente di modificare la modalità di esecuzione dell'ordinamento automatico o di creare una routine di ordinamento personalizzato.
Quando si utilizza il controllo LinqDataSource, è possibile personalizzare l'ordinamento impostando la proprietà AutoSort su false. Quindi è possibile creare un gestore per l'evento Selecting.
Quando si utilizzano i controlli ObjectDataSource o SqlDataSource, è possibile usufruire delle funzionalità di ordinamento mediante la proprietà SortParameterName. È possibile impostare la proprietà SortParameterName sul nome del parametro che contiene un'espressione di ordinamento passata al controllo origine dati. L'espressione di ordinamento è un elenco di campi delimitati da virgole da utilizzare per l'ordinamento e, eventualmente, l'identificatore DESC utilizzato per applicare un ordinamento decrescente. Per informazioni sul formato dell'espressione di ordinamento, vedere la proprietà DataView.Sort.
Il parametro identificato dalla proprietà SortParameterName viene passato al SelectMethod del controllo ObjectDataSource, oppure viene passato come elemento dell'insieme dei parametri al SelectCommand del controllo SqlDataSource. Il controllo ObjectDataSource è in grado di utilizzare l'informazione che gli viene passata nel parametro di ordinamento per restituire i dati con un ordinamento. Per il controllo SqlDataSource, è necessario indicare il nome di una stored procedure che può utilizzare il parametro di ordinamento e restituire i dati ordinati, perché non è possibile passare un parametro come elemento di una clausola ORDER BY.
Nell'esempio di codice riportato di seguito viene illustrata una dichiarazione del controllo ObjectDataSource che identifica un parametro denominato sortColumns come nome di parametro di ordinamento:
<asp:ObjectDataSource
ID="EmployeesObjectDataSource"
TypeName="Samples.AspNet.Controls.NorthwindEmployee"
SortParameterName="SortColumns"
EnablePaging="true"
StartRowIndexParameterName="StartRecord"
MaximumRowsParameterName="MaxRecords"
SelectMethod="GetAllEmployees" >
</asp:ObjectDataSource>
<asp:ObjectDataSource
ID="EmployeesObjectDataSource"
TypeName="Samples.AspNet.Controls.NorthwindEmployee"
SortParameterName="SortColumns"
EnablePaging="true"
StartRowIndexParameterName="StartRecord"
MaximumRowsParameterName="MaxRecords"
SelectMethod="GetAllEmployees" >
</asp:ObjectDataSource>
Nell'esempio di codice riportato di seguito viene illustrato un metodo nell'oggetto origine per il controllo ObjectDataSource. Il metodo viene identificato come SelectMethod. Il parametro identificato dalla proprietà SortParameterName viene utilizzato per l'ordinamento dei dati recuperati dal database.
Public Shared Sub Initialize()
' Initialize data source. Use "Northwind" connection string from configuration.
If ConfigurationManager.ConnectionStrings("Northwind") Is Nothing OrElse _
ConfigurationManager.ConnectionStrings("Northwind").ConnectionString.Trim() = "" Then
Throw New Exception("A connection string named 'Northwind' with a valid connection string " & _
"must exist in the <connectionStrings> configuration section for the application.")
End If
_connectionString = _
ConfigurationManager.ConnectionStrings("Northwind").ConnectionString
_initialized = True
End Sub
' Select all employees.
<DataObjectMethod(DataObjectMethodType.Select, True)> _
Public Shared Function GetAllEmployees(sortColumns As String, startRecord As Integer, maxRecords As Integer) As DataTable
VerifySortColumns(sortColumns)
If Not _initialized Then Initialize()
Dim sqlCommand As String = "SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode FROM Employees "
If sortColumns.Trim() = "" Then
sqlCommand &= "ORDER BY EmployeeID"
Else
sqlCommand &= "ORDER BY " & sortColumns
End If
Dim conn As SqlConnection = New SqlConnection(_connectionString)
Dim da As SqlDataAdapter = New SqlDataAdapter(sqlCommand, conn)
Dim ds As DataSet = New DataSet()
Try
conn.Open()
da.Fill(ds, startRecord, maxRecords, "Employees")
Catch e As SqlException
' Handle exception.
Finally
conn.Close()
End Try
If ds.Tables("Employees") IsNot Nothing Then _
Return ds.Tables("Employees")
Return Nothing
End Function
'''''
' Verify that only valid columns are specified in the sort expression to aSub a SQL Injection attack.
Private Shared Sub VerifySortColumns(sortColumns As String)
If sortColumns.ToLowerInvariant().EndsWith(" desc") Then _
sortColumns = sortColumns.Substring(0, sortColumns.Length - 5)
Dim columnNames() As String = sortColumns.Split(",")
For Each columnName As String In columnNames
Select Case columnName.Trim().ToLowerInvariant()
Case "employeeid"
Case "lastname"
Case "firstname"
Case ""
Case Else
Throw New ArgumentException("SortColumns contains an invalid column name.")
End Select
Next
End Sub
public static void Initialize()
{
// Initialize data source. Use "Northwind" connection string from configuration.
if (ConfigurationManager.ConnectionStrings["Northwind"] == null ||
ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString.Trim() == "")
{
throw new Exception("A connection string named 'Northwind' with a valid connection string " +
"must exist in the <connectionStrings> configuration section for the application.");
}
_connectionString =
ConfigurationManager.ConnectionStrings["Northwind"].ConnectionString;
_initialized = true;
}
// Select all employees.
[DataObjectMethod(DataObjectMethodType.Select, true)]
public static DataTable GetAllEmployees(string sortColumns, int startRecord, int maxRecords)
{
VerifySortColumns(sortColumns);
if (!_initialized) { Initialize(); }
string sqlCommand = "SELECT EmployeeID, LastName, FirstName, Address, City, Region, PostalCode FROM Employees ";
if (sortColumns.Trim() == "")
sqlCommand += "ORDER BY EmployeeID";
else
sqlCommand += "ORDER BY " + sortColumns;
SqlConnection conn = new SqlConnection(_connectionString);
SqlDataAdapter da = new SqlDataAdapter(sqlCommand, conn);
DataSet ds = new DataSet();
try
{
conn.Open();
da.Fill(ds, startRecord, maxRecords, "Employees");
}
catch (SqlException e)
{
// Handle exception.
}
finally
{
conn.Close();
}
if (ds.Tables["Employees"] != null)
return ds.Tables["Employees"];
return null;
}
//////////
// Verify that only valid columns are specified in the sort expression to avoid a SQL Injection attack.
private static void VerifySortColumns(string sortColumns)
{
if (sortColumns.ToLowerInvariant().EndsWith(" desc"))
sortColumns = sortColumns.Substring(0, sortColumns.Length - 5);
string[] columnNames = sortColumns.Split(',');
foreach (string columnName in columnNames)
{
switch (columnName.Trim().ToLowerInvariant())
{
case "employeeid":
break;
case "lastname":
break;
case "firstname":
break;
case "":
break;
default:
throw new ArgumentException("SortColumns contains an invalid column name.");
break;
}
}
}
Per ulteriori informazioni, vedere Creazione di un oggetto di origine del controllo ObjectDataSource.