0

ASPNET_Compiler.exe からこのエラーを「渡す」のに問題があります。

エラー CS0103: 名前 'TestMath' は現在のコンテキストに存在しません。

ユーザー コントロール (.cs) ファイルから TestMath 内で呼び出される関数は、コンテキスト (スコープ/名前空間/...) の外にあります。TestMath 内のメソッドを呼び出す行をコメント アウトすると、コンパイルが機能し、ユーザー コントロール (WebApplication 内から DLL を参照) も機能します。

「TestMath」クラスは、-1+3 を返す 1 つの静的メソッド「Get」を含む静的クラスです (非静的を作成しようとしましたが、うまくいきませんでした)。

Visual Studio (MSBuild) での通常のビルドは機能しますが、ご存じのとおりです。.ascx ファイルを DLL に正しくパックしません。

以下を含む .rar を添付しました。

  1. テストライブラリ

1 つの .ascx コントロールと 1 つの数学クラスが含まれています

「BuildAssembly.cmd」を実行するビルド後のイベントが含まれており、次に aspnet_compiler と aspnet_merge を実行します。

  1. WebSite - ライブラリからコントロールを表示する 1 つの .aspx ページ。

エラーが発生する行は、Label.ascx.cs の 18 行目にあります。

Lbl.Text += " MATH: " + TestMath.Get()

何か提案はありますか?当ててみて?.ascx.cs 以外のクラスでメソッドを呼び出すことは禁止されていますか? ああ…でも、その言葉には何かがあります!つまり、次のように、User-Control クラス内に Math-class をコピーすると、次のようになります。

public class Label : UserControl
{
    ..methods of label
    public class Math
    { 
      public static Get()
    }
}

ソリューションはコンパイルされ、両方のクラス内でメソッドを呼び出すことができます...しかし、私たち全員が望むように; 私も例外ではありません。他のオブジェクトも呼び出せるようにしたいのです (私は既に行っていますが、それらは GAC に存在するだけです...)...だから、うーん...基本的には; aspnet_compiler はどこで dll を探しますか...

サンプル ソリューションをダウンロード: http://s000.tinyupload.com/?file_id=76690332418132532036

ソリューションを C:\Solutions\Test に解凍すると、Visual Studio 2010、Windows 7... .NET フレームワーク 4 以降を想定して、ほとんど問題なく実行できます。

それ以外の場合、ここにいくつかのコードがあります: ASCX

<%@ Control Language="C#" 
AutoEventWireup="true" 
ClassName="TestLibrary.Controls.Label"
CodeFile="Label.ascx.cs"
CodeBehind="Label.ascx.cs"
Inherits="TestLibrary.Controls.LabelCode" %>



Test

 <asp:Label runat="server" ID="Lbl"></asp:Label>

ASCX コードビハインド

protected void Page_Load(object sender, EventArgs e)
    {
        Lbl.Text = "CodeBehindText...";
        Lbl.Text += " MATH: " + TestMath.Get();
    }

テスト数学

 public static int Get()
    {
        return -1 + 3;
    }

BuildAssembly.cmd

SET compiler_path=%systemroot%\Microsoft.NET\Framework64\v4.0.30319
SET aspnet_merge=C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\aspnet_merge.exe
SET websiteproject=C:\Solutions\Test\TestLibrary\TestLibrary
SET compiled=C:\Solutions\Test\TestLibrary\TestLibrary\Compiled
SET outputfolder=C:\Solutions\Test\TestLibrary\TestLibrary\bin\Release
SET outputfilenamedll=TestLibrary.dll
%compiler_path%\aspnet_compiler.exe -p "%websiteproject%" -c -f -d -v / %compiled%
"%aspnet_merge%" %compiled% -o %outputfilenamedll%
COPY /Y %compiled%\bin\%outputfilenamedll% %outputfolder%\%outputfilenamedll%
RMDIR /s /q %compiled%

2015 年に ASCX でこのように「曖昧」になったのはなぜでしょうか? ああ、数年前に作成された ascx ファイルを再利用して、それらをライブラリに永久にパックし、アセンブリに署名し、SharePoint 環境にインポートしたいと考えていました...

4

1 に答える 1

0

さらに4時間試行錯誤した後、これが解決策です。

  1. ascx コントロールにクラス名 (クラス名、.ascx ファイル内の属性) を指定します。

    Control Language="C#" AutoEventWireup="true" CodeFile="~/Control.ascx.cs" Inherits="Control" ClassName="UnqiueControlName [実際のクラス名とは異なる必要があります]" %>

  2. すべてのカスタム生成 DLL をクラス ライブラリの BIN フォルダーにコピーします。

    または cmd を実行: gacutil /i

カスタム dll (たとえば、Common.dll) を gac に登録するルートを試してみましたが、apsnet_compiler がすべての gac フォルダー内でアセンブリを見つけられないように見えるため、さらに時間がかかるようです (はい、さらに多くのフォルダーがあります)。 1 つの場所/フォルダだけではありません)。GAC、MSIL、32ビット、64ビットを更新する地獄を忘れないでください...プロジェクトでDLLを参照すると、ビルドされます...後でDLLを更新しますが、GACを更新するのを忘れます.. .そして実行時に、アプリケーションは GAC で DLL を使用します... GAC への登録は、セットアップ/実際のインストールを通じてのみ行う必要があります...

  1. .ascx ファイルを含むクラス ライブラリを Visual Studio で通常どおりにコンパイルします。
  2. すべての .ascx ファイルの「CodeBehind」属性を「CodeFile」に変更します (両方を持つことはできません。これは、質問のエラーの一部でした)

  3. aspnet_compiler を使用してプロジェクト全体をコンパイルします。

    aspnet_compiler.exe -v projectName -p "projectFolder (csproj が存在する場所)" "outputFolder"

  4. aspnet_compiler が作成した "outputFolder" で aspnet_merge.exe を実行します。

    aspnet_merge.exe "outputFolder" -o "nameOfDLLYouWant.dll"

  5. これで .ascx ファイルを含む 1 つの dll ができたので、intellisense と MSBuild が適切に機能するように、すべての ascx ファイルの CodeFile 属性を CodeBehind に戻します。

  6. 新しい Web アプリケーション プロジェクトを作成し、その中のすべてを削除し、新しく作成した DLL への参照を追加して、新しい Default.aspx を追加します。

  7. アセンブリと名前空間を .aspx サイト (または web.conf) に登録します。 <%@ Register Assembly="UserControl" NameSpace="NameSpaceOfWhereYourControlLives" TagPrefix="uc">

  8. body タグの間に追加します。ライブラリで定義されている ClassName 属性の名前を使用することを忘れないでください (.ascx ファイルの最初の行)。

または、「すべてを実行する」単純な cmd ファイル (必要な DLL を Bin にコピーし、CodeBehind、CodeFile、コンパイル、dll の新しい dll へのマージを行ったり来たりします):

@ECHO ON
setlocal enabledelayedexpansion

::--------------------------------------------------------------------------------------------------------
::--------------------------------------------------------------------------------------------------------
::VARIABLES
::--------------------------------------------------------------------------------------------------------
::--------------------------------------------------------------------------------------------------------
SET project=C:\Solutions\UserControlLibrary
REM Notice that project variable above ends with project name below!
SET projectname=UserControlLibrary
SET projectcompiledfolder=C:\Temp\UserControlLibraryCompiled
SET outputdll=UserControlLibrary.dll
REM Configuration is either release or debug, depending on which "mode" you are building against in Visual studio.
SET projectconfiguration=Release

::--------------------------------------------------------------------------------------------------------
::--------------------------------------------------------------------------------------------------------
::LOGIC
::--------------------------------------------------------------------------------------------------------
::--------------------------------------------------------------------------------------------------------
call:ReplaceFunction %project% "CodeBehind", "CodeFile"

call:CopyLibraryReference Common, Release, %project%

call:ProjectCompile %projectname%, %project%, %projectcompiledfolder%

call:ProjectMerge %projectcompiledfolder%, %outputdll%, %project%, %projectconfiguration%

call:ReplaceFunction %project% "CodeFile", "CodeBehind"

RMDIR /s /q %projectcompiledfolder%

exit


::---------------------------------------------------------------------------`-----------------------------`
::---------------------------------------------------------------------------`-----------------------------`
::FUNCTIONS
::---------------------------------------------------------------------------`-----------------------------`
::---------------------------------------------------------------------------`-----------------------------`
:CopyLibraryReference <referenceName> <referenceConfiguration> <project>
SET referenceName=%~1
SET referenceConfiguration=%~2
SET project=%~3
REM Solution folder, containing a bunch of Library projects, such as "Common", "ActiveDirectory", "BusinuessLogic" and our UserControlLibrary...
SET lib=C:\Solutions\
COPY /Y "%lib%%referenceName%\bin\%referenceConfiguration%\%referenceName%.dll" "%project%\bin\%referenceName%.dll" 
goto:eof

:ProjectCompile <projectname> <project> <projectcompiledfolder>
SET projectname=%~1
SET project=%~2
SET projectcompiledfolder=%~3
REM Path to compiler might vary, also if you want 32 or 64 bit... this might need to change
SET compiler=C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_compiler.exe
"%compiler%" -v %projectname% -p "%project%" "%projectcompiledfolder%"
goto:eof


:ProjectMerge <projectcompiledfolder> <outputdll> <project> <projectconfiguration>
SET projectcompiledfolder=%~1
SET outputdll=%~2
SET project=%~3
SET projectconfiguration=%~4
REM Path to merger might vary, also if you want 32 or 64 bit... this might need to change
SET merger=C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\aspnet_merge.exe
"%merger%" "%projectcompiledfolder%" -o %outputdll%
COPY /Y "%projectcompiledfolder%\bin\%outputdll%" "%project%\bin\%projectconfiguration%\%outputdll%"
goto:eof

:ReplaceFunction <projectFolder> <replaceValue> <replaceWith>
set projectFolder=%~1
REM tempfile name can be anything...
set tempfile=%~1\replaceascxbuildv1.txt
set replaceValue=%~2
set replaceWith=%~3
for /f %%f in ('dir /b /s %projectFolder%\*.ascx') do ( 
    for /f "tokens=1,* delims=¶" %%A in ( '"type %%f"') do (
        SET string=%%A
        SET modified=!string:%replaceValue%=%replaceWith%!
        echo !modified! >> %tempfile%
    )
    del %%f
    move %tempfile% %%f
)
goto:eof

これを「.cmd」ファイルに追加し、Post Build Event で cmd ファイルを実行します。ビルドは通常より遅い (もちろん) ため、私である必要はありません。ユーザー コントロールが多すぎると、これが追加されることを理解してください。その後、自由に複数のプロジェクトを作成してください。:P

結論: Visual Studio でビルドを実行するだけで、すべてが自動的に実行され、コードを記述できるようになりました。これを自分で使用する場合は、自分のファイルとプロジェクトへの独自のパスを把握するだけで済みますが、1 つまたは 2 つのパスが関数自体に記述されていることに注意してください。;)

編集: リストは実際には 0 から始まりますが、2 が 2 つあることがわかります... バグ!

于 2015-05-29T14:06:37.330 に答える