Smart 404 en asp.net

Suite à la lecture de cet article :

http://wwww.geekswithblogs.net/shahed/archive/2007/10/23/116278.aspx

L'auteur Shahed Khan (le createur de smartcodegenerator) nous explique comment recuperer le nom de la page qui manque et d'en substituer une autre via le gestionnaire standard d'erreur d'asp.net

Pour traiter cette problèmatique en s'aidant de google je propose une autre alternative via un handler spécifique :

google404.ashx (par exemple)

<%@ WebHandler Language="C#" Class="Google404" %>

using System;
using System.Web;

public class Google404 : IHttpHandler
{
    public void ProcessRequest (HttpContext context)
    {
        string path = context.Request["aspxerrorpath"];
        if (!string.IsNullOrEmpty(path))
        {
            path = path.Replace(".aspx","");
            path = path.Replace("/","");
        }
        string site = HttpUtility.UrlEncode("site:monsite.com");
        string tuning = HttpUtility.UrlEncode("T:white;L:http://monsite.com/images/Logo.png;AWFID:5e296cf425978c37;");
        string r = string.Format("http://www.google.com/custom?hl=fr&q={0}+{1}&cof={2}",site, path, tuning);
        context.Response.Redirect(r,true);
    }

    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}

et la configuration du handler dans web.config

    <customErrors mode="On">
      <error statusCode="404" redirect="~/google404.ashx" />
    </customErrors>

Cette variante de traitement part du principe que google connait mieux votre site que vous ;) , la partie tuning est optionnelle il s'agit juste de customiser la page de resultat de google pour faire apparaitre son propre logo pour ne pas trop perturber l'utilisateur qui ne s'attends probablement pas a ce resultat.

Comment changer l'url de deploiement clickonce sans desinstallation / reinstallation

 

J'ai eu pour un cas de figure à regler pour un certain nombre de client , le serveur sur lequel etait deployé une application clickonce ne convenait plus et l'url indiquée etait une url locale du type http://monserveur/, il y avait une solution qui consistait à changer chaque fichiers "host" de chaque poste ou etait installé l'application et de faire pointer vers une nouvelle ip et sur le nouveau serveur ajouter le bon host header. Pas vraiment pratique, d'autant plus qu'il faut refaire cette manip pour les nouveaux clients.

Ensuite j'ai pensé à une desinstallation puis réinstallation sur chaque poste, les utilisateurs n'etant pas tous très "abiles" avec ces manipulations, il fallait que je me deplace sur chaque poste pour réaliser cette modification moi meme. Pas pratique non plus.

En regardant de plus près le manifest de deployement  , on peut voir dans la section <deployment><deploymentProvider> l'attribut codebase comme indiqué ici, celui-ci indique l'emplacement de deployement.

il suffit de modifier la valeur entrée par la nouvelle url de deployement, resigner le manifest avec le certificat, voici une petite methode pour le faire, le premier paramètre est l'emplacement du manifeste de deployement, le deuxieme est l'emplacement du certificat et le troisième est le mot de passe du certificat.

public static void SignFile(string manifestFileName, string certificatFileName, string password)
{
    Uri timestampUrl = null;
    X509Certificate2 cert = new X509Certificate2(certificatFileName, password);
    bool flag = false;
    X509Certificate2 storedCert = null;
    if (flag = ValidateCertificate(cert, certificatFileName))
    {
        storedCert = cert;
    }
    X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
    store.Open(OpenFlags.OpenExistingOnly);
    foreach (X509Certificate2 certificate2 in store.Certificates)
    {
        if ((certificate2.GetCertHashString().ToLower() == null) && (flag = ValidateCertificate(certificate2, null)))
        {
            storedCert = certificate2;
        }
    }
    SecurityUtilities.SignFile(storedCert, timestampUrl, manifestFileName);
}

Publier le nouveau manifest de deployement signé dans l'emplacement existant et surtout ne pas oublier de pusher les fichiers sur le nouvel emplacement.

Clickonce : Comment remplacer la page publish.htm générée par Visual Studio 2005 par une page dynamique

 

Lors d'une publication clickonce, Visual Studio 2005 à la bonté de nous générer une belle page html contenant les elements nécéssaires pour le deployement d'une application clickonce, mais au fur et à mesure des mise à jour pusher cette page est plutot contraingnant , de plus le code html en interne n'est pas ce fait de mieux si l'on veut customiser la page.

Pour améliorer cette page, il faut savoir qu'il existe une API s'occupant des manifest de deployement et application , pour cela il faut utiliser l'assembly Micorosft.Build.Tasks, elle est présente dans le GAC.

Pour recuperer les information du manifest de deployement en cours il suffit de proceder comme ceci , par exemple dans le PageLoad :

string path = HttpContext.Current.Request.MapPath(".") + @"\myapp.application";

Microsoft.Build.Tasks.Deployment.ManifestUtilities.DeployManifest manifest
            = (Microsoft.Build.Tasks.Deployment.ManifestUtilities.DeployManifest)Microsoft.Build.Tasks.Deployment.ManifestUtilities.ManifestReader.ReadManifest(path, true);

Une fois chargées, toutes les informations sont disponibles pour venir peupler une page de setup dynamique

manifest.AssemblyIdentity.Version (pour obtenir la version de l'application en cours)

Comment générer un bootstrapper clickonce sans utiliser visual studio

 

Dans le cadre d'une software factory , j'avais besoin de pouvoir generer à la volée des bootstrappers clickonce personnalisés par client, et bien entendu visual studio 2005 ne s'y prete pas dans ce cas, mais Microsoft a tout prevu, il suffit d'utiliser MSBuild, une tache est dediée a ce sujet, on peut trouver le documentation sur le site msdn a l'adresse suivante :

http://msdn2.microsoft.com/en-us/library/ms164294(VS.80).aspx

dans un premier temps il faut produire un ficher (bootstrapper.xml) contenant les informations pour produire le bootstrap, de la forme suivante par exemple :

 

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
    <BootstrapperPackage Include="Microsoft.Data.Access.Components.2.8">
      <Visible>False</Visible>
      <ProductName>Microsoft Data Access Components 2.8</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.Net.Framework.2.0">
      <Visible>False</Visible>
      <ProductName>.NET Framework 2.0</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="Microsoft.ReportViewer.8.0">
      <Visible>False</Visible>
      <ProductName>Microsoft Visual Studio 2005 Report Viewer</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
    <BootstrapperPackage Include="{511DAC48-6CBB-43a3-A64D-0182F2A9EBC2}">
      <Visible>False</Visible>
      <ProductName>.NET Framework 3.0</ProductName>
      <Install>true</Install>
    </BootstrapperPackage>
   </ItemGroup>

   <Target Name="Bootstrapper">
      <GenerateBootstrapper
         ApplicationName="Mon application"
         ApplicationUrl=http://deploy.mondomaine.com"
     ApplicationFile="monapp.application"
         BootstrapperItems="@(BootstrapperFile)"
         Culture="fr"
         CopyComponents="True"
         OutputPath="c:\temp" />
   </Target>
</Project>

En l'occurence j'ai volontairement indiqué que je voulais que soient installés MDac 2.8 le framework 2.0 et 3.0 et report viewer

mon url de deployement est http://deploy.mondomaine.com/monapp.application

Pour produire le fichier setup.exe il faut lancer la commande suivante :

C:\Windows\Microsoft.NET\Framework\v2.0.50727\MSBuild.exe "bootstrapper.xml"

il ne reste plus qu'a recuperer le fichier dans le repertoire c:\temp (parametre outputpath du fichier xml)