2009-04-02 3 views
4

다른 프로젝트에서 ASP 사용자 정의 컨트롤을 재사용하려고하는데 문제가 발생했습니다. ScottGu의 게시물 http://weblogs.asp.net/scottgu/archive/2005/08/28/423888.aspx을 읽었고 그의 패턴을 따르려고했지만 컨트롤의 자식 컨트롤이 초기화되지 않았습니다.ASP의 다른 프로젝트에서 사용자 정의 컨트롤 사용

내 설정 : Visual Studio 2008을 사용하고 있습니다. 여러 다른 솔루션에 배포 할 컨트롤을 보유 할 솔루션을 만들었습니다. 이 솔루션에는 다음이 포함되어, 이제 (내 사용자 컨트롤로)이 "ClassLibrary"

  • 웹 애플리케이션 프로젝트를 호출하자이 "가장 안쪽의"을 부르 자 (모델 코드 등)

    • 라이브러리 프로젝트를
    • 가장 안쪽 프로젝트의 쉘 역할을 다른 웹 애플리케이션 프로젝트의 숫자의 그들 중 하나를 생각하자 "외부"

    t 를 호출 이것 뒤에 숨어있는 것은 가장 안쪽에는 기능이 포함되어 있고 Outer에는 가장 안쪽의 컨트롤을 특정 프레임 워크에서 작동시키는 데 필요한 특수 수정이 포함되어 있다는 것입니다.

    ClassLibrary이 같은 코드 (이것이 내가하기 위해 만든 데모 설정에서 모든 있는지가, 다른하지 뭔가 내가 ASP 문제 일을 하였다)이 있습니다

    using System; 
    
    namespace ClassLibrary { 
        public class LibraryClass { 
         public long getLong() { 
          return DateTime.Now.Ticks; 
         } 
    
         public string getString() { 
          return DateTime.Now.ToString(); 
         } 
        } 
    } 
    

    가장 안쪽 라이브러리 프로젝트를 참조를 잘 작동합니다. 코드 숨김와

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

    :

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

    내가 등록하여 가장 안쪽 프로젝트의 사용자 컨트롤을 사용하는 가장 안쪽의 프로젝트에서 테스트 페이지가이이 프로젝트에 UserControl이의 예입니다 다음 구문을 사용합니다.

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

    외부 프로젝트는 내부 클래스 및 ClassLibrary를 참조합니다. 간단한 코드 숨김와

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

    : 그리고 가장 안쪽의 컨트롤의 다음 등록으로 된 UserControls 포함 시스템을 사용하여; using System.Web.UI;

    namespace Outer.Control { 
        public partial class TopControl : UserControl { 
         public bool ShowType1 { get; set; } 
    
         protected void Page_Load(object sender, EventArgs e) { 
          Control1.Visible = ShowType1; 
          Control2.Visible = !ShowType1; 
         } 
        } 
    } 
    

    내면의 프로젝트에서 테스트 페이지를 실행할 때 오류가없고 모든 것이 작동합니다. 내가 Outer 프로젝트를 실행할 때 Innermost.UserControls.WebUserControlX의 자식 컨트롤이 설정되지 않았다는 것을 알려주는 NullReferenceException을 얻습니다.

    스택 트레이스 : 사람이 면밀한 관찰을하고자하는 경우

    [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 
    

    내가 솔루션으로 테스트 설정을 제공 할 수 있습니다.

    마지막으로, 내 질문은 : 컨트롤의 ChildControl이 예상대로 설정되지 않는 이유는 무엇입니까? 외부 컨트롤의 초기화에서 CreateChildControls()을 실행하더라도 생성되지 않습니다.내 측 프로젝트를 외부 프로젝트에서 사용하기 위해 컴파일해야하는 특별한 방법이 있습니까?

    도움이 될 것입니다.

  • 답변

    6

    나는이 설정을 전에 시도한 적이 없지만 지금 무슨 일이 일어나고 있는지 추측 할 수 있습니다. UserCotnrol은 경로가 아닌 참조로로드됩니다. 참조로 생성하려고합니다. 내부 프로젝트에서 참조하는 방법과 외부 프로젝트와 다른 점을 주목하십시오. 나는 이것을 작동 시키려면 .ascx 파일의 경로 위치를 참조해야한다고 생각합니다.

    빠른 검색은 VS 2005에서이 작업을 수행하는 방법을 보여 주지만 개념은 VS 2008에서 동일해야합니다.이 정보는 here입니다.

    또 다른 옵션은 디자인 화면을 사용하지 않고 LoadControl 메서드를 사용하여 컨트롤을로드하고 .ascx 파일의 경로를 전달하는 것입니다.

    편집 위에서 언급 한 링크에서 중요한 점은 외부 응용 프로그램에서 .ascx 파일에 액세스 할 수 있도록 설정해야한다는 것입니다. 위의 링크는 pre-build 명령을 사용하여 .ascx 파일을 외부 프로젝트의 하위 폴더로 복사하여이 작업을 수행합니다. 내부 프로젝트를 마치 재배포하는 것처럼 생각하십시오. 어셈블리뿐만 아니라 .ascx 파일도 함께 제공해야합니다. 사용자가이를 사용하려면 .ascx 파일을 참조하고 프로젝트에서 해당 어셈블리를 참조해야합니다. 당신도 똑같은 일을해야합니다.

    좀 더 분명하길 바랍니다.

    +0

    컨트롤이 다른 응용 프로그램에있는 경우 LoadControl에서 오류가 발생합니다. 가상 경로 ... 허용되지 않는 다른 응용 프로그램에 매핑됩니다. – Ruslan

    관련 문제