Table des matières
ASP.NET
- Voir aussi : ASP.NET AJAX, ASP.NET MVC
Outils nécessaires
- Pour développer
- Éditeur de texte
- Framework .NET
- Compilateur C# / VB.NET ou autre parmi ceux fournis avec .NET → JScript, J# ou C++ .NET
- Pour compiler →
C:\>vbc
ouC:\>csc
- Pour tester / rouler
- Serveur IIS
Outils souhaités
- Visual Studio .NET (2003 → 2010), mais payant
- ASP.NET Development Server, inclu avec Visual Studio
- Webmatrix, mais probablement remplacé par Visual Web Developer 2008 Express
- MonoDevelop, IDE gratuit
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> </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");
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 : fr
→ fr-CA
, en
→ en_US
, etc.
Changer la culture par programmation
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US");
Utiliser un fichier ressource sans localisation
- Dans Visual Studio 2008, aller dans le menu Projet, Propriétés de [Nom du projet].
- Aller dans l'onglet Ressources.
- Créer un nouveau fichier.
- Le nouveau fichier
Resources.resx
se trouvera dans le répertoireProperties
, au même endroit queAssembly.cs
. - Entrer les données
Nom
etValeur
. - Pour référencer une ressource en particulier :
string s = SupportRequestApp.Properties.Resources.String1;
- 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
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
<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
Hyperlink
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>
DropDownList
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 :
- Dans
web.config
<configuration> <system.web> <compilation debug="true" /> </system.web> </configuration>
- 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
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 :
- Changer le fichier
web.config.comments
dansC:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG
- Changer le
web.config
de l'application (généralement préférable)
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="*" />