【问题标题】:User Controls (asp.net, ascx-files) inside a C# class library, build error (aspnet_compiler.exe)C# 类库中的用户控件(asp.net、ascx-files),构建错误(aspnet_compiler.exe)
【发布时间】:2015-05-28 14:02:53
【问题描述】:

无法从 ASPNET_Compiler.exe“传递”此错误:

错误 CS0103:名称“TestMath”在当前上下文中不存在。

在 TestMath 中从用户控件 (.cs) 文件调用的函数位于上下文之外(范围/命名空间/...)。如果我注释掉调用 TestMath 中的方法的行,那么编译工作和我的用户控件(从 WebApplication 中引用 DLL)也是如此。

“TestMath”类是一个静态类,它包含一个静态方法“Get”,它返回 -1+3(我也尝试过创建它非静态...但运气不好)。

Visual Studio (MSBuild) 中的正常构建工作,但众所周知;它不会正确地将 .ascx 文件打包到 DLL 中。

我附上了一个.rar,其中包含:

  1. 测试库

包含 1 个 .ascx 控件和 1 个数学类

包含一个构建后事件,它运行“BuildAssembly.cmd”,后者又运行 aspnet_compiler 和 aspnet_merge。

  1. 网站 - 一个 .aspx 页面,用于显示库中的控件。

给出错误的行位于 Label.ascx.cs 中的第 18 行:

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

有什么建议吗?猜一下?禁止在 .ascx.cs 之外的类中调用方法?哦……但是这些话是有道理的!意思是说;如果我在 User-Control 类中复制数学类,如下所示:

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 或更高版本。 em>

否则,这里有一些代码: 澳交所

<%@ 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 环境...

【问题讨论】:

    标签: c# user-controls ascx aspnet-compiler aspnet-merge


    【解决方案1】:

    又经过 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文件夹中找到程序集(是的,不止一个位置/文件夹)。让我们不要忘记更新 GAC、MSIL、32 位、64 位...如果您在项目中引用 DLL,那么它会构建...稍后您更新 DLL,但忘记更新 GAC.. .并且在运行时应用程序将使用 GAC 中的 DLL...注册到 GAC 只能通过安装程序/实际安装...

    1. 像往常一样在 Visual Studio 中编译您的类库,其中包含 .ascx 文件。
    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 文件的 dll,我们将所有 ascx 文件的 CodeFile 属性交换回 CodeBehind,以便智能感知和 MSBuild 正常工作。

    6. 创建一个新的 Web 应用程序项目,删除其中的所有内容,添加对新创建的 DLL 的引用并添加一个新的 Default.aspx。

    7. 在您的 .aspx 站点(或 web.conf)上注册程序集和命名空间:

    8. 在body标签之间添加,记得使用库中定义的ClassName-attribute的名称(.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”文件中,然后在构建后事件时运行 cmd 文件。构建比平时慢(当然),所以你不必是我,明白如果你有太多的用户控件,这加起来。然后随意创建几个项目。 :P

    结论: 现在我只需在 Visual Studio 中构建,一切都是自动的,我终于可以编写一些代码了!如果您自己使用过它,您所需要的只是找出您自己的文件和项目的路径,但请注意:一两个路径是在函数本身中编写的。 ;)

    编辑:列表实际上从 0 开始,但我确实看到有两个 2...错误!

    【讨论】:

      猜你喜欢
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-21
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多