Table des matières

ASP.NET

Outils nécessaires

Outils souhaités

Différences

Applications ASP.NET
WinForms WebForms

Événements

Postback

Pour savoir si un Postback a été fait

if (!Page.IsPostBack)
{
    //traitement
}

Référence

Code HTML dynamique

Image avec query string

Si on veut inclure une image, créée dynamiquement en ASP.NET (exemple mon_image.aspx) a partir d'une autre page (principale.aspx) et lui envoyer des informations en query string on peut le faire de plusieurs façons.

Dans le code Page_Load de principale.aspx.cs inclure :

imgMonImage.ImageUrl = "mon_image.aspx" + "?x=" + x.ToString() + "&y=" + y.ToString();

Dans la page principale.aspx l'image sera appellée comme ceci :

<asp:Image ID="imgMonImage" runat="server" ImageUrl="mon_image.aspx" />

Peut se faire aussi avec des autrement (style ASP)1) :

<asp:Image ID="imgMonImage" runat="server" ImageUrl="mon_image.aspx<%="?x="+x.ToString()+"&y="+y.ToString()%>" />

Récupérer les données en query string

float x, y;
if (!float.TryParse(context.Request.Params["x"], out x)) x = 0F;
if (!float.TryParse(context.Request.Params["y"], out y)) y = 0F;
int id;
if (int.TryParse(Request.QueryString["id"], out id)) {
    // Faire le travail 
}

User controls

Créer un user control est très simple, le fichier .ascx peut ressembler à :

<%@ Control Language="C#" AutoEventWireup="true"
CodeFile="Header.ascx.cs" Inherits="Header" %>
<table width="100%" border="0" bgcolor="blue">
  <tr>
    <td><font face="Verdana,Arial" size="6" color="yellow"><b>
    User Control Test Page</b></font>
    </td>
  </tr>
  <tr>
    <td align="right"><font size="3" color="white"><b>
    Made by someone.</b></font>&nbsp;&nbsp;&nbsp;
    </td>
  </tr>
</table>

Et dans la page (.aspx), où l'on veut inclure le user control on met en entête :

<%@ Register TagPrefix="uctest" TagName="Header" Src="Header.ascx" %>

Et plus loin, à l'endroit où l'on veut vraiment voir apparaitre l'objet :

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="HeaderTest.aspx.cs"
Inherits="HeaderTest" %>
<%@ Register TagPrefix="uctest" TagName="Header" Src="Header.ascx" %>
<html>
  <head>
    <title>HeaderHost</title>
  </head>
  <body>
    <form id="Form1" method="post" runat="server">
      <uctest:Header id="Header1" runat="server"></uctest:Header>
    </form>
  </body>
</html>

Créer des propriétés dans le code :

public String Username
{
    get {return _username;}
    set {_username = value;}
}

Déclarer le contrôle dans web.config et qui doit être dans la section <configuration>/<system.web>/<pages>/<controls> :

<add tagPrefix="uctest" src="~/Controls/Header.ascx" tagName="header"/>

Cela permet d'éviter de déclarer le contrôle dans chacune des pages, ce qui peut nuire à la maintenance.

Gestion d'état

View State

La première approche pour garder les données, c'est la méthode ViewState2). Elle est simple a utiliser et elle est nativement intégrée dans ASP.NET. Les inconvénients sont que sa portés se limite à la page elle-même et les objets doivent être serialisables.

exemple pour une donnée simple
ViewState["compteur"] = 1;   // store la valeur
 
// récupérer la valeur
if (ViewState["compteur"] != null)
{
  compteur = (int)ViewState["compteur"];
}
exemple avec un objet (qui doit être serialisable)
[Serializable]
public class Client
{
    public string Prenom;
    public string Nom;
    public Customer(string prenom, string nom)
    {
        Prenom = this.prenom;
        Nom = this.nom;
    }
}
un client dans un viewstate
Client clt = new Client("Marsala", "Simons");
ViewState["clientcourant"] = clt;
incorporant le ViewState
private int? _employeeId;
private int? EmployeeId
{
    get
    {
        if (_employeeId == null)
        {
            if (ViewState["_employeeId"] != null)
            {
                _employeeId = (int)ViewState["_employeeId"];
            }
            else
            {
                _employeeId = null;
            }
        }
        return _employeeId;
    }
    set
    {
        _employeeId = value;
        if (value == null)
        {
            ViewState.Remove("_employeeId");
        }
        else
        {
            ViewState["_employeeId"] = value;
        }
    }
}

Session State

S'utilise de façon semblable au ViewState.

Session["nom"] = "Pierre Jean-Jacques";
//ou
Session.Add("nom","Pierre Jean-Jacques");
 
//récupérer
string nom = (string)Session("nom");

sessionhelper.zip

Afficher des messages d'erreur

    Response.Buffer = true;
    Response.Clear();
    Response.ContentType = "text/plain";
    Response.Write("Message d'erreur : " + e.Message.ToString());

Si une page personnalisée d'erreur existe mais qu'on veut tout de même voir le vrai problème, ajouter une méthode Page_Error:

public void Page_Error(object sender, EventArgs e)
{
    Exception objErr = Server.GetLastError().GetBaseException();
    string err = "<b>Error Caught in Page_Error event</b><hr><br>" +
            "<br><b>Error in: </b>" + Request.Url.ToString() +
            "<br><b>Error Message: </b>" + objErr.Message.ToString() +
            "<br><b>Stack Trace:</b><br>" +
                      objErr.StackTrace.ToString();
    Response.Write(err.ToString());
    Server.ClearError();
}

Localization

Pour aller chercher la langue envoyée par le navigateur web3) :

using System.Globalization;
 
//...
    CultureInfo ci;
    if ((Request.UserLanguages != null) && (Request.UserLanguages.Length > 0))
    {
        ci = new CultureInfo(Request.UserLanguages[0]);
    }
    else
    {
        ci = new CultureInfo("fr-CA");
    }
    System.Threading.Thread.CurrentThread.CurrentUICulture = ci;

Par programmation

La localisation de chaînes de caractère peuvent se faire automatiquement avec l'outil Generate Local Resource de Visual Studio. Pour construire des chaines personnalisées qui pourront être traduites dans différentes langues, il faut utiliser soit GetLocalResourceObject ou GetGlobalResourceObject. Ces deux méthodes retournent un objet, c'est la raison pourquoi on utilise Convert.ToString().

  lblUnLabel.Text = Convert.ToString(GetLocalResourceObject("lblUnLabelResource1.Text")) + " " + strChainePersonnalisee;

On peut aussi utiliser cette technique avec les textes dynamiques. UpdateText est une ressource localisée qui a comme valeur : Cet article a été créé par {0} le {1} et a été modifié par {2} le {3} et a aussi comme valeur : This article has been created by {0} on {1}, and modified by {2} on {3}..

this.Literal1.Text = string.Format(Convert.ToString(GetLocalResourceObject("UpdateText")), userCreate, dateCreate.ToShortDateString(), userModif, dateModif.ToShortDateString());

LCID

Culture LCID
en-US 1033
es-SP 3082
fr-CA 3084
ru 1049

Autres : http://www.microsoft.com/globaldev/reference/lcid-all.mspx

Problèmes liés à la culture

Il est possible de rencontrer une erreur de style :

Culture 'fr' is a neutral culture. It cannot be used in formatting and parsing and therefore cannot be set as the thread's current culture.

Cette erreur peut être visible que sur Firefox car il peut envoyer une culture sur deux lettres (fr) en premier lieu. Comme le System.Threading.Thread.CurrentThread.CurrentCulture et System.Threading.Thread.CurrentThread.CurrentCulture ne peuvent pas être spécifiés dans une langue trop neutre, il faut la préciser le pays ou la région : frfr-CA, enen_US, etc.

Changer la culture par programmation

System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");

Utiliser un fichier ressource sans localisation

  1. Dans Visual Studio 2008, aller dans le menu Projet, Propriétés de [Nom du projet].
  2. Aller dans l'onglet Ressources.
  3. Créer un nouveau fichier.
  4. Le nouveau fichier Resources.resx se trouvera dans le répertoire Properties, au même endroit que Assembly.cs.
  5. Entrer les données Nom et Valeur.
  6. Pour référencer une ressource en particulier :
    string s = SupportRequestApp.Properties.Resources.String1;
  7. Il est aussi possible d'utiliser le formattage de chaine:
    // Bonjour dans le resource file = "Bonjour {0} {1}, comment allez-vous ?"
    string s2 = string.Format(SupportRequestApp.Properties.Resources.Bonjour, nom, prenom);

Pas besoin de s'occuper de culture, localisation, etc.

Ressources

http://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.aspx

Envoyer un courriel

using System.Net.Mail;
using System.Net.Mime;
 
string strBody = "C'est le corps du message.";
string strSubject = "Exemple de email";
string strFromAddr = "source@domain.tld";
string strToAddr = "destination@domain.tdl";
 
MailMessage mmEmail = new MailMessage(strFromAddr, strToAddr, strSubject, strBody);
SmtpClient smtpclient = new SmtpClient("mail.domain.tld", 25);
NetworkCredential nc = new NetworkCredential("username", "password");
smtpclient.Credentials = nc;
 
smtpclient.Send(mmEmail);

On peut mettre les informations relatives au serveur SMTP dans le web.config :

  <system.net>
    <mailSettings>
      <smtp>
        <network 
             host="relayServerHostname" 
             port="portNumber"
             userName="username"
             password="password" />
      </smtp>
    </mailSettings>
  </system.net>

En developpement, si l'on ne veut pas utiliser un serveur SMTP, on peut écrire dans un fichier :

<configuration>
    <system.net>
        <mailSettings>
            <smtp deliveryMethod="SpecifiedPickupDirectory">
                <specifiedPickupDirectory pickupDirectoryLocation="c:\email" />
            </smtp>
        </mailSettings>
    </system.net>
</configuration>

Composants ASP.NET

Événements

Contrôle Évenement Signature de la méthode
GridView OnRowDataBound protected void GridView1_OnDataRowBound(object sender, GridViewRowEventArgs e)
GridView RowEditing protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
GridView RowCancelingEdit protected void GridView1_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e)
Repeater OnItemDataBound protected void Repeater1_OnItemDataBound (object sender, RepeaterItemEventArgs e)

Source : http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowediting.aspx

GridView

Certains exemples ci-dessous fonctionnent grâce au cadriciel d'application .netTiers.
<asp:GridView ID="PersonnesGridView" runat="server" AutoGenerateColumns="False" BackColor="White" BorderColor="#000000" BorderStyle="Groove" BorderWidth="1px" CellPadding="1">
    <Columns>
        <asp:BoundField DataField="Prenom" HeaderText="Prénom" ReadOnly="True" />
        <asp:BoundField DataField="Nom" HeaderText="Nom" ReadOnly="True" />
        <asp:BoundField DataField="Courriel" HeaderText="Courriel" ReadOnly="True" />
        <asp:BoundField DataField="DateNaissance" HeaderText="Date de naissance" ReadOnly="True" />      
        <asp:BoundField DataField="DateBegin" HeaderText="Date" DataFormatString="{0:d}"
            ReadOnly="True" ItemStyle-Width="70px" ItemStyle-HorizontalAlign="Center">
            <ItemStyle HorizontalAlign="Center" Width="70px"></ItemStyle>
        </asp:BoundField>                     
    </Columns>
    <FooterStyle BackColor="White" ForeColor="#330099" />
    <RowStyle BackColor="White" ForeColor="#330099" />
    <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
    <PagerStyle BackColor="#FFFFCC" ForeColor="#330099" HorizontalAlign="Center" />
    <HeaderStyle BackColor="#F06300" Font-Bold="True" ForeColor="#FFFFCC" />
</asp:GridView>
<asp:GridView ID="PersonnesGridView" runat="server" AutoGenerateColumns="False" BackColor="White" BorderColor="#000000" BorderStyle="Groove" BorderWidth="1px" CellPadding="1">
    <Columns>
        <asp:TemplateField HeaderText="Nom">
            <ItemTemplate>
                <%# ((Etudiant)Container.DataItem).ToString() %>
            </ItemTemplate>
        </asp:TemplateField>                  
        <asp:TemplateField HeaderText="Date de naissance">
            <ItemTemplate>
                <%# Html.GetShortDate(((Etudiant)Container.DataItem).Naissance) %>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Qty" >
            <ItemTemplate>
                <%# Eval(((Etudiant)Container.DataItem).Note.ToString(), "{0:999,99}")%>
            </ItemTemplate>
        </asp:TemplateField>  
    </Columns>
</asp:GridView>

Commande supprimer

Il peut être intéressant d'ajouter une commande à chaque enregistrement du GridView pour l'effacer.

Il faut d'abord ajourter une colonne au GridView:

de la colonne supprimer au GridView
<asp:TemplateField HeaderText="" HeaderStyle-Width="45px">
    <ItemTemplate>
        <asp:LinkButton runat="server" id="deleteItemButton" OnClientClick="return confirm('Êtes-vous certain ?');" CommandArgument="<%# ((Person)Container.DataItem).Id.Value.ToString() %>" OnCommand="DeleteItem" Text="Supprimer"></asp:LinkButton>
    </ItemTemplate>
</asp:TemplateField>

Ensuite, implémenter la méthode DeleteItem telle que spécifiée avec la valeur de OnCommand :

DeleteItem
protected void DeleteItem(object sender, CommandEventArgs e)
{
    if (e.CommandArgument.ToString().Length > 0)
    {
        int id = Convert.ToInt32(e.CommandArgument.ToString());
        Person personne = new Personne(id);
        personne.Delete();
    }
}    

DataKeyNames

<asp:GridView ID="GridView1" DataKeyNames="Id" >
int Id = int.Parse(GridView1.DataKeys[e.NewEditIndex].Value.ToString());

Changer dynamiquement les entêtes de colonnes

GridView1.Columns[0].HeaderText = "Nom de la colonne";

Accéder aux contrôles

foreach (GridViewRow gvr in gv.Rows)
{
    CheckBox chk = (CheckBox)gvr.FindControl("nomDuCheckBox");
}

Événements du GridView

    protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("GridView1_RowCreated");
    }
    protected void GridView1_DataBinding(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("GridView1_DataBinding");
    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("GridView1_RowDataBound");
    }
    protected void GridView1_DataBound(object sender, EventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("GridView1_DataBound");
    }

Raccourcir une chaine

S'il y a une description, du texte qui peut être long, on peut afficher qu'une partie de celle-ci. On ne peut pas directement raccourcir le texte dans le fichier ASPX avec <%# Eval(“Description”).ToString().Substring(0, 100) + “…” %> car si le texte est plus court, il y aura une erreur.

protected string ValidateString(object String)
{
    if ((String.ToString().Length > 100))
    {
        return String.ToString().Substring(0, 100) + "...";
    }
    else
    {
        return String.ToString();
    }
}

Et dans le fichier ASPX :

<asp:TemplateField HeaderText="Description">
    <ItemTemplate>
        <%# ValidateString(Container.DataItem("Description")) %>
    </ItemTemplate>
</asp:TemplateField>

Source : http://forums.asp.net/t/1011868.aspx


Peut se faire autrement, lors du ItemDataBound du RadGrid :

protected void RadGrid1_ItemDataBound(object sender, Telerik.Web.UI.GridItemEventArgs e)
{
    if (e.Item is GridDataItem)
    {
        GridDataItem dataBoundItem = e.Item as GridDataItem;
        if (dataBoundItem["Description"].Text.Length >= 100)
        {
            dataBoundItem["Description"].Text = dataBoundItem["Description"].Text.Substring(0, 100) + " <div class=\"tronque\">[tronqué]</div>";
        }
    }
}

Ressources

LinqDataSource

Un fournisseur de données qui utilise LINQ-to-SQL en ASP.NET :

<asp:LinqDataSource 
  ContextTypeName="ExampleDataContext" 
  TableName="Products" 
  GroupBy="new(ProductCategory, Color)"
  Select="new(Key,
          It As Products,
          Max(ListPrice) As MaxListPrice, 
          Min(ListPrice) As MinListPrice)"
  ID="LinqDataSource1" 
  runat="server">
</asp:LinqDataSource>
Select="new (ContactName, City, ContactTitle)" 
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
    ContextTypeName="sqlGFDataContext"
    EnableDelete="True"
    EnableInsert="True"
    EnableUpdate="True"
    OrderBy="commentID desc"
    TableName="gf_game_comments"
    OnDeleted="lvComments_OnDeleted">
</asp:LinqDataSource>

Source : LinqDataSource Class (MSDN)

UpdatePanel

Pour utiliser un hyperlien ASP.NET avec un mailto:. L'exemple montre aussi la possibilité d'utiliser dans une grille.

<asp:HyperLink NavigateUrl='<%# Bind("Email", "mailto:{0}") %>' Text='<%# Bind("Email") %>' runat="server" ID="hlEmail"></asp:HyperLink>
 
<asp:HyperLink id="lnkEmail" runat="server" text='<%#DataBinder.Eval(Container, "DataItem.email") %>'
NavigateUrl='<%#DataBinder.Eval(Container, "DataItem.email","MAILTO:{0}")%>'></asp:HyperLink>

Sélection qui change

Si un DropDownList ne garde pas sa sélection après un postback c'est peut-être simplement dû au fait que les éléments y sont rajoutés. Ajouter les éléments au premier chargement de la page :

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    { //ajouter les éléments (binding)
    }
}

DataBind avec LINQ

DropDownList ddlCompanyList = (DropDownList )PanelBar1.FindItemByValue("form").FindControl("ddlCompanyList");
ddlCompanyList .DataTextField = "CompanyID";
ddlCompanyList .DataValueField = "CompanyName";
ddlCompanyList .DataSource = from c in db.Company
                                    select new { c.CompanyID, c.CompanyName };
ddlCompanyList .DataBind();

Autre exemple avec la liaison de la valeur courante et la liste :

public List<Employee> GetListeEmployes(AccesBDDataContext db)
{
    return (from e in db.Employees
            select e).ToList();
}
 
protected void rgGestionAcces_ItemCreated(object sender, GridItemEventArgs e)
{
    // ...
    Employee employee = db.Employees.Single(e => e.IdEmployee == employeeId);
    cbxEmployes.DataValueField = "IdEmployee";
    cbxEmployes.DataTextField = "EmployeeName";
    cbxEmployes.DataSource = GetListeEmployes(db);
    cbxEmployes.DataBind();
    cbxEmployes.SelectedValue = employee.IdEmployee.ToString(); 
}

Utilisation du JavaScript

Ajout d'attribut au contrôle

Le JavaScript peut être utilisé de différentes façons, voici un exemple avec l'ajout d'attribut au contrôle :

protected void Page_Load(object sender, System.EventArgs e)
{
     TextBox1.Attributes.Add("onMouseOver", "alert('Le curseur passe au-dessus du TextBox1.');");
     TextBox2.Attributes.Add("onMouseOver", "alert('Le curseur passe au-dessus du TextBox2.');");
}

Authentification Windows

Il est possible de d'authentifier ou d'obtenir des informations sur les utilisateurs Windows. Dans Web.config configurer comme ceci :

 <configuration>
    <system.web>
        <authentication mode="Windows" />
         <authorization>
             <deny users="?"/>
          </authorization>
    </system.web>
</configuration>

Le ? de la ligne <deny users="?"/> signifie les utilisateurs anonymes. Juste la ligne <authentication mode="Windows" /> peut être suffisante.

Pour aller chercher les informations dans la page :

TextBox txtLogon = (TextBox)PanelBar1.FindItemByValue("form").FindControl("txtLogin");
System.Security.Principal.IPrincipal user = HttpContext.Current.User;
txtLogon.Text = user.Identity.Name;

Avec Firefox

Firefox supporte l'authentification par Windows (NTLM), pour vérifier, aller dans about:config et voir les paramètres :

Paramètre Statut Type Valeur
network.automatic-ntlm-auth.allow-proxies default boolean true
network.automatic-ntlm-auth.trusted-uris default string

Utilisation d'Active Directory

Active Directory peut servir à aller chercher d'autres informations tel que le prénom et le nom.

System.Security.Principal.WindowsIdentity wi = System.Security.Principal.WindowsIdentity.GetCurrent();
string[] a = Context.User.Identity.Name.Split('\\');
 
System.DirectoryServices.DirectoryEntry ADEntry = new System.DirectoryServices.DirectoryEntry("WinNT://" + a[0] + "/" + a[1]);
txtName.Text = ADEntry.Properties["FullName"].Value.ToString();

L'ajout d'une référence à System.DirectoryServices peut être nécessaire.

Ressources

Web.config

Debugging mode

Le mode debug peut être modifié de deux façons :

  1. Dans web.config
    <configuration>
        <system.web>
            <compilation debug="true" />
        </system.web>
    </configuration>
  2. Dans machine.config
    <configuration>
        <system.web>
              <deployment retail="true" />
        </system.web>
    </configuration>

Accéder par programmation

HttpContext context = HttpContext.Current;
if (context.IsDebuggingEnabled)
{
    // code
}
using System.Configuration;
using System.Web.Configuration;
//...
CompilationSection configSection =   (CompilationSection)ConfigurationManager.GetSection("system.web/compilation");
if (configSection.Debug)
{
    // code
}

Gérer des données binaires ou dynamiques

Générer une image dynamiquement

Il est possible de générer une image à l'aide d'un HTTPHandler.

Bitmap objBitmap = new Bitmap(200, 200);
Graphics objGraphics = Graphics.FromImage(objBitmap);
 
objGraphics.Clear(Color.White);
Brush b1 = new SolidBrush(Color.Red);
Rectangle rect = new Rectangle(10, 10, 30, 30);
objGraphics.FillRectangle(b1, rect);
 
// Save the image to the OutputStream
Response.ContentType = "image/jpeg";
objBitmap.Save(Response.OutputStream, ImageFormat.Jpeg);
 
objBitmap.Dispose();
objGraphics.Dispose(); 

Générer dynamiquement des documents PDF

Créer un nouveau fichier ASPX et dans la fonction Page_Load inscrire (utilise la librarie iTextSharp4)):

protected void Page_Load(object sender, EventArgs e)
{
    Response.Clear();
    Response.ContentType = "application/pdf";
    MemoryStream m = new MemoryStream();
    Document document = new Document();
    PdfWriter writer = PdfWriter.GetInstance(document, m);
    document.Open();
 
    document.Add(new Paragraph("Généré le "+DateTime.Now.ToString()));
    document.Add(new Paragraph("Bonjour à tous !"));
    document.Close();
 
    writer.Flush();
    Response.OutputStream.Write(m.GetBuffer(), 0, m.GetBuffer().Length);
    Response.OutputStream.Flush();
    Response.OutputStream.Close();
    Response.End(); 
}

Pour des exemple, voir les démonstrations d'iTextSharp.

Téléverser des données binaires

Exemple pour téléverser (uploader vers le serveur) des fichiers. Cet exemple utilise LINQ-to-SQL pour l'accès à la base de données.

protected void btnUpload_Click(object sender, EventArgs e)
{
    if (fuFileUploader.HasFile && fuFileUploader.PostedFile.ContentLength > 0)
    {
        string path_file_name = fuFileUploader.PostedFile.FileName;
        string ext = Path.GetExtension(path_file_name).Replace(".", "");
        string file_name = Path.GetFileNameWithoutExtension(path_file_name);
        string file_title = txtFileTitle.Text.Trim();
        HelperDataClassesDataContext db = new HelperDataClassesDataContext();
 
        try
        {
            byte[] file_byte = fuFileUploader.FileBytes;
            Linq.Binary file_binary = new Linq.Binary(file_byte);
 
            ControlDocument cd = new ControlDocument
            {
                guid = Guid.NewGuid(),
                file_ext = ext,
                file_nm = file_name.Trim(),
                file_title=file_title,
                file_bin = file_binary,
                is_active = true,
                upload_page_type = rblLocation.SelectedValue,
                upload_dt = DateTime.Now,
                upload_by = UtilUniverse.Common.CurrentUserLogin.Trim()
            };
            db.ControlDocuments.InsertOnSubmit(cd);
        }
        finally
        {
            db.SubmitChanges();
        }
    }
}

Source : Linq to Sql: Upload binary file
Voir aussi : http://www.telerik.com/help/aspnet-ajax/upload_raduploadmanipulatingfiles.html

* FileUpload dans un ModalPopupExtender

Télécharger des données binaires

On peut créer un gestionnaire générique (Generic handler) dans le cas d'une utilisation avec ASP.NET .

using System.IO;
 
//...
public void ProcessRequest(HttpContext context)
{
    int id;
    if (int.TryParse(context.Request.Params["id"], out id)) {
        CustomDataContext db = new CustomDataContext();
 
        Attachment attachment = db.Attachment.Single(a => a.IdAttachment == id);
 
        FileInfo file = new FileInfo(attachment.FileName);
        context.Response.ContentType = GetContentType(file.Extension);
        context.Response.AddHeader("Content-Disposition", " filename=" + attachment.FileName);
        context.Response.AddHeader("Content-Length", attachment.Data.Length.ToString());
        context.Response.BinaryWrite(attachment.Data.ToArray());
        context.Response.Flush();
    }
    else {
        context.Response.ContentType = "text/plain";
        context.Response.Write("Erreur, fichier introuvable.");
    }
}
 
private string GetContentType(string fileExtension)
{
    switch (fileExtension) {
        case ".jpg":
        case ".jpeg":
            return "image/jpeg";
        case ".doc":
            return "application/msword";
        case ".xls":
            return "application/vnd.ms-excel";
        case ".pdf":
            return "application/pdf";             
        default:
            return "application/octet-stream";
    }
}

Si le fichier téléchargé est un type de fichier géré par le fureteur (ex: images, PDF, etc), ceux-ci s'ouvriront directement dans le navigateur. Pour permettre d'afficher une boite de dialogue Enregistrer sous…, il faut changer l'entête de la réponse avec attachment :

Response.AppendHeader("Content-Disposition","attachment; filename=document.pdf");

Limitation de la taille du fichier

Les fichiers qui sont téléversés vers le serveur avec le FileUpload sont limités par une taille de 4 Mo. Pour changer la configuration, il faut soit :

Mettre sous le node <system.web> et changer la valeur de maxRequestLength.

<httpRuntime 
 executionTimeout="110" 
 maxRequestLength="4096" 
 requestLengthDiskThreshold="80" 
 useFullyQualifiedRedirectUrl="false" 
 minFreeThreads="8" 
 minLocalRequestFreeThreads="4" 
 appRequestQueueLimit="5000" 
 enableKernelOutputCache="true" 
 enableVersionHeader="true" 
 requireRootedSaveAsPath="true" 
 enable="true" 
 shutdownTimeout="90" 
 delayNotificationTimeout="5" 
 waitChangeNotification="0" 
 maxWaitChangeNotification="0" 
 enableHeaderChecking="true" 
 sendCacheControlHeader="true" 
 apartmentThreading="false" />

Il faudra peut-être changer aussi le paramètre executionTimeout qui ira avec l'augmentation ou la diminution de maxRequestLength.

== Sources :

Bouts de code

Détecter le navigateur

private void Button1_Click(object sender, System.EventArgs e)
{
    System.Web.HttpBrowserCapabilities browser = Request.Browser;
    string s = "Browser Capabilities\n"
        + "Type = "                    + browser.Type + "\n"
        + "Name = "                    + browser.Browser + "\n"
        + "Version = "                 + browser.Version + "\n"
        + "Major Version = "           + browser.MajorVersion + "\n"
        + "Minor Version = "           + browser.MinorVersion + "\n"
        + "Platform = "                + browser.Platform + "\n"
        + "Is Beta = "                 + browser.Beta + "\n"
        + "Is Crawler = "              + browser.Crawler + "\n"
        + "Is AOL = "                  + browser.AOL + "\n"
        + "Is Win16 = "                + browser.Win16 + "\n"
        + "Is Win32 = "                + browser.Win32 + "\n"
        + "Supports Frames = "         + browser.Frames + "\n"
        + "Supports Tables = "         + browser.Tables + "\n"
        + "Supports Cookies = "        + browser.Cookies + "\n"
        + "Supports VBScript = "       + browser.VBScript + "\n"
        + "Supports JavaScript = "     + 
            browser.EcmaScriptVersion.ToString() + "\n"
        + "Supports Java Applets = "   + browser.JavaApplets + "\n"
        + "Supports ActiveX Controls = " + browser.ActiveXControls 
              + "\n";
    TextBox1.Text = s;
}

Source : http://msdn.microsoft.com/en-us/library/3yekbd5b.aspx

Contrôles de validation

<asp:RegularExpressionValidator ID="revEmail" runat="server" Display="Dynamic" ErrorMessage="Entrez un courriel valide." ValidationExpression="^[\w\.\-]+@[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*(\.[a-zA-Z]{2,3}){1,2}$" ControlToValidate="txtEmail"></asp:RegularExpressionValidator>
<asp:RequiredFieldValidator ID="rfvEmail" runat="server" Display="Dynamic" ControlToValidate="txtEmail" ErrorMessage="Le courriel est requis." Text="*" />

Codes sources externes

Collections de composants

Bonnes pratiques

1)
À tester…
2)
Source : Pro ASP.NET 2.0 in C# 2005 (Apress, 2005)
3)
Source : Pro ASP.NET 2.0 in C# 2005 (Apress, 2005), p.609.