Partager via


Tri de données avec des contrôles de source de données

Mise à jour : novembre 2007

Vous pouvez afficher des données dans une page Web ASP.NET à l'aide d'un contrôle de source de données et d'un contrôle lié aux données. Certains contrôles de données permettent aux utilisateurs de trier les données sans utiliser de code.

Si vous souhaitez autoriser les utilisateurs à trier des données au moment de l'exécution, vous pouvez utiliser un contrôle LinqDataSource, ObjectDataSource, SqlDataSourceou AccessDataSource comme contrôle de source de données. Pour afficher les données que les utilisateurs peuvent trier, vous pouvez utiliser un contrôle GridView ou ListView.

Présentation d'une interface utilisateur pour le tri

Vous pouvez créer une interface utilisateur permettant d'effectuer un tri. Toutefois, les contrôles GridView et ListView fournissent un tri par défaut.

Le contrôle GridView prend en charge le tri sur une seule colonne sans qu'aucune programmation soit nécessaire. Vous affectez la valeur true à la propriété AllowSorting pour créer automatiquement le texte d'en-tête de chaque colonne sous la forme d'un bouton de lien qui passe une expression de tri au contrôle de source de données. Vous pouvez personnaliser davantage la fonction de tri du contrôle GridView en gérant l'événement de tri. Pour plus d'informations, consultez Tri des données dans un contrôle serveur Web GridView.

Vous pouvez trier les données affichées dans un contrôle ListView en ajoutant un bouton au modèle LayoutTemplate du contrôle et en attribuant la valeur "Sort" à la propriété CommandName du bouton. Affectez à la propriété CommandArgument du bouton le nom de la colonne sur laquelle vous souhaitez effectuer un tri. Cliquez sur le bouton Trier pour basculer le sens de tri entre Ascending et Descending. Pour plus d'informations, consultez Vue d'ensemble du contrôle serveur Web ListView et Procédure pas à pas : affichage, pagination et tri de données à l'aide du contrôle serveur Web ListView.

Activation du tri dans un contrôle de source de données

Les contrôles de source de données LinqDataSource, ObjectDataSource, SqlDataSource et AccessDataSource fournissent une prise en charge intégrée du tri. Le contrôle LinqDataSource prend en charge le tri lorsque la propriété AutoSort a la valeur true (valeur par défaut), comme dans l'exemple suivant :

<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>

Les contrôles SqlDataSource et AccessDataSource ne prennent en charge le tri que lorsque leur propriété DataSourceMode a la valeur DataSet (soit la valeur par défaut), comme dans l'exemple suivant :

<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" />

Le contrôle ObjectDataSource ne prend en charge le tri que si l'objet retourné par SelectMethod est un objet DataSet, DataTable ou DataView. ObjectDataSource prend également en charge la récupération des résultats de la source de données avec leur tri.

Tri personnalisé

Vous pouvez personnaliser la manière dont les contrôles liés aux données et les contrôles de source de données exécutent le tri. Cela vous permet de modifier le mode de tri automatique ou de créer une routine de tri personnalisée.

Lorsque vous utilisez le contrôle LinqDataSource, vous pouvez personnaliser le tri en affectant la valeur false à la propriété AutoSort. Vous pouvez ensuite créer un gestionnaire pour l'événement Selecting.

Lorsque vous utilisez les contrôles ObjectDataSource ou SqlDataSource, vous pouvez profiter des fonctions de tri à l'aide de la propriété SortParameterName. Vous pouvez affecter à la propriété SortParameterName le nom du paramètre qui contient une expression de tri actuellement passée au contrôle de source de données. L'expression de tri est une liste, délimitée par des virgules, de champs servant de critères de tri (plus, de façon facultative, l'identificateur DESC pour trier en ordre décroissant). Pour plus d'informations sur le format de l'expression de tri, consultez la propriété DataView.Sort.

Le paramètre identifié par la propriété SortParameterName est passé à SelectMethod du contrôle ObjectDataSource, ou passé dans le cadre de la collection de paramètres à SelectCommand du contrôle SqlDataSource. Le contrôle ObjectDataSource peut utiliser les informations qui lui ont été passées dans le paramètre de tri pour retourner les données triées. Pour le contrôle SqlDataSource, vous devez fournir le nom d'une procédure stockée capable de prendre le paramètre de tri et de retourner les données triées, parce que vous ne pouvez pas passer de paramètre dans le cadre d'une clause ORDER BY.

L'exemple de code suivant montre une déclaration de contrôle ObjectDataSource qui identifie un paramètre nommé sortColumns comme nom du paramètre de tri :

<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>

L'exemple de code suivant montre une méthode dans l'objet source pour le contrôle ObjectDataSource. La méthode est identifiée comme étant SelectMethod. Le paramètre identifié par la propriété SortParameterName sert à trier les données récupérées de la base de données.

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;
    }
  }
}

Pour plus d'informations, consultez Création d'un objet source de contrôle ObjectDataSource.

Voir aussi

Autres ressources

Contrôles serveur Web de sources de données