2009-04-02 7 views
4

J'essaie de réutiliser mes contrôles utilisateur ASP dans d'autres projets et j'ai rencontré un problème. J'ai lu le message de ScottGu sur http://weblogs.asp.net/scottgu/archive/2005/08/28/423888.aspx et j'ai essayé de suivre ses schémas, mais les fichiers enfants de mes contrôles ne sont pas en cours d'exécution. J'utilise Visual Studio 2008 J'ai créé une solution pour contenir les contrôles que je veux distribuer à plusieurs autres solutions. Cette solution contient:Utilisation des contrôles utilisateur d'autres projets dans ASP

    projets de bibliothèque
  • (pour le code de modèle, etc.), nous appellerons ce "ClassLibrary"
  • un projet WebApp (avec mes contrôles utilisateur), nous appellerons ce "INTIME"
  • un certain nombre d'autres projets WebApp faisant office Bennes pour le projet INTIME, nous allons considèrent l'un d'eux et l'appellent « extérieur »

le t La raison derrière cela est qu'Innermost contient la fonctionnalité et Outer contient toutes les modifications spéciales nécessaires pour que les contrôles Innermost fonctionnent dans un cadre particulier.

Le ClassLibrary a du code comme celui-ci (ce qui est tout à partir d'une démo-setup j'ai fait pour vous assurer qu'il a un problème ASP, pas autre chose que je faisais):

using System; 

namespace ClassLibrary { 
    public class LibraryClass { 
     public long getLong() { 
      return DateTime.Now.Ticks; 
     } 

     public string getString() { 
      return DateTime.Now.ToString(); 
     } 
    } 
} 

Innermost fait référence au projet de bibliothèque et fonctionne bien. Ceci est un exemple d'un UserControl dans ce projet:

<%@ Control Language="C#" AutoEventWireup="true" 
    CodeBehind="WebUserControl1.ascx.cs" 
    Inherits="Innermost.UserControls.WebUserControl1" %> 
<asp:Label ID="testLabel" runat="server"/> 

avec code-behind:

using System; 
using System.Web.UI; 
using ClassLibrary; 

namespace Innermost.UserControls { 
    public partial class WebUserControl1 : UserControl { 
     protected void Page_Load(object sender, EventArgs e) { 
      LibraryClass c = new LibraryClass(); 
      testLabel.Text = "Your number is " + c.getLong(); 
     } 
    } 
} 

J'ai une page de test dans le projet Innermost qui utilise les contrôles utilisateur du projet Innermost en vous inscrivant les avec la syntaxe suivante:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test1.aspx.cs" 
    Inherits="Innermost.Test1" %> 

<%@ Register TagPrefix="inner" TagName="Control1" 
    Src="~/UserControls/WebUserControl1.ascx" %> 
<%@ Register TagPrefix="inner" TagName="Control2" 
    Src="~/UserControls/WebUserControl2.ascx" %> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head runat="server"> 
    <title></title> 
</head> 
<body> 
<form id="form1" runat="server"> 
<div> 
    Control 1: 
    <inner:Control1 ID="control1" runat="server" /> 
    <br /> 
    Control 2: 
    <inner:Control2 ID="control2" runat="server" /> 
</div> 
</form> 
</body> 
</html> 

Le projet Outer références Innermost et ClassLibrary; et contient UserControls avec l'enregistrement suivant des contrôles Innermost:

<%@ Control Language="C#" AutoEventWireup="true" 
    CodeBehind="TopControl.ascx.cs" Inherits="Outer.Control.TopControl" %> 
<%@ Register TagPrefix="inner" Assembly="Innermost" 
    Namespace="Innermost.UserControls" %> 
<inner:WebUserControl1 ID="Control1" runat="server"/> 
<inner:WebUserControl2 ID="Control2" runat="server"/> 

Avec un code-behind simple: using System; en utilisant System.Web.UI; Lorsque je lance la page de test dans le projet Innermost, je n'obtiens aucune erreur et tout fonctionne. Lorsque je lance le projet Outer, je reçois NullReferenceException s me disant que les contrôles enfants du Innermost.UserControls.WebUserControlX n'ont pas été définis.

StackTrace:

[NullReferenceException: Object reference not set to an instance of an object.] 
    Innermost.UserControls.WebUserControl1.Page_Load(Object sender, EventArgs e) in c:\Test\ASP\Innermost\Innermost\UserControls\WebUserControl1.ascx.cs:9 
    System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14 
    System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35 
    System.Web.UI.Control.OnLoad(EventArgs e) +99 
    System.Web.UI.Control.LoadRecursive() +50 
    System.Web.UI.Control.LoadRecursive() +141 
    System.Web.UI.Control.LoadRecursive() +141 
    System.Web.UI.Control.LoadRecursive() +141 
    System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627 

Je peux fournir la configuration de test des solutions si quelqu'un veut regarder de plus près à ce sujet. Donc, enfin, ma question est: Pourquoi les contrôles enfants des contrôles ne sont pas configurés comme prévu? Même si je cours CreateChildControls() dans l'initialisation des contrôles externes, ils ne sont pas créés.Existe-t-il un moyen particulier de compiler le projet Innermost pour le projet Outer?

Toute aide serait grandement appréciée!

Répondre

6

Je n'ai pas tous essayé cette configuration auparavant, mais je peux deviner ce qui se passe. UserCotnrols sont censés être chargés par chemin, pas par référence. Vous essayez de les créer par référence. Remarquez la différence entre la façon dont vous vous référez à eux dans le projet interne et en quoi elle diffère du projet externe. Je crois que pour que cela fonctionne, vous devrez vous référer à l'emplacement du fichier .ascx.

Une recherche rapide montre comment cela peut être fait dans VS 2005 mais le concept devrait être le même dans VS 2008. Vous pouvez trouver cette information here.

Une autre option consiste à ne pas utiliser la surface de conception et à charger les contrôles à la place en utilisant la méthode LoadControl, en transmettant le chemin d'accès aux fichiers .ascx.

Modifier La chose importante à prendre à partir du lien ci-dessus je mentionné est que vous devez rendre les fichiers .ascx Accessable pour votre application extérieure. Le lien ci-dessus le fait en utilisant une commande pre-build pour copier les fichiers .ascx dans un sous-dossier du projet externe. Pensez au projet interne comme si vous alliez le redistribuer. Vous devez donner non seulement l'assemblage, mais aussi les fichiers .ascx. Pour que les utilisateurs le consomment, ils doivent référencer les fichiers .ascx et faire référence à votre projet par votre projet. Vous devez faire la même chose aussi.

J'espère que c'est un peu plus clair.

+0

Si les contrôles résident dans différentes applications, comme cela semble être le cas, LoadControl génère une erreur: Le chemin virtuel ... est mappé à une autre application, ce qui n'est pas autorisé. – Ruslan

Questions connexes