2010-05-21 116 views
4

使用PreApplicationStartMethod属性发生在我身上的奇怪事情。我在我的最新项目中实现了它。在AssemblyInfo.cs中我有以下行:PreApplicationStartMethod属性导致异常

[assembly: PreApplicationStartMethod(typeof(MyAssembly.Initializer), "Initialize")] 

的类型和方法是这样的:

namespace MyAssembly 
{ 
    public static class Initializer 
    { 
     public static void Initialize() 
     { 
      TranslationKeys.Initialize(); 
     } 
    } 
} 

当我重建我的应用程序,并在浏览器中我得到以下错误加载它:

The method specified by the PreApplicationStartMethodAttribute on assembly 'MyWebApp, Version=0.0.1.0, Culture=neutral, PublicKeyToken=null' cannot be resolved. Type: 'MyAssembly.Initializer', MethodName: 'Initialize'. Verify that the type is public and the method is public and static (Shared in Visual Basic).

我真的不知道问题出在哪里。

回答

10

奇怪的是,我们在ASP.NET团队中使用了这个功能,并没有遇到这个问题。为了帮助调试,你可以尝试运行下面的代码,它做了类似于ASP.NET找到方法的东西吗?

运行它的最好方法是创建一个控制台应用程序并将该代码放在那里。然后,只需调用它,将它传递给您看到该问题的程序集。然后,您会想要调试它并仔细追踪它,看看发生了什么。

顺便说一句,在这之前,仔细检查你是否将该属性放在包含该类的相同组件上。即它不能指向不同组件中的类型。

下面是代码尝试:

using System; 
using System.Web; 
using System.Reflection; 

public class TestClass { 
    public static void TestPreStartInitMethodLocation(Assembly assembly) { 
     var attributes = (PreApplicationStartMethodAttribute[])assembly.GetCustomAttributes(typeof(PreApplicationStartMethodAttribute), inherit: true); 

     if (attributes != null && attributes.Length != 0) { 
      PreApplicationStartMethodAttribute attribute = attributes[0]; 

      MethodInfo method = null; 
      // They must be in the same assembly! 
      if (attribute.Type != null && !String.IsNullOrEmpty(attribute.MethodName) && attribute.Type.Assembly == assembly) { 
       method = FindPreStartInitMethod(attribute.Type, attribute.MethodName); 
      } 

      if (method == null) { 
       throw new HttpException("Couldn't find attribute"); 
      } 
     } 
    } 

    public static MethodInfo FindPreStartInitMethod(Type type, string methodName) { 
     MethodInfo method = null; 
     if (type.IsPublic) { 
      method = type.GetMethod(methodName, BindingFlags.Public | BindingFlags.Static | BindingFlags.IgnoreCase, 
          binder: null, 
          types: Type.EmptyTypes, 
          modifiers: null); 
     } 
     return method; 
    } 
} 
+2

顺便说一句,在这之前,仔细检查你是否将该属性放在包含该类的相同组件上。即它不能指向不同组件中的类型。 --------------------------------------- 谢谢!那就是诀窍。在我的解决方案中我有不同的项目。 Initialize类与我的Web应用程序不同。 – Joop 2010-06-21 08:46:25

+0

但是。考虑它并查看堆栈跟踪我认为这是一个奇怪的事情,这个类需要在同一个项目/程序集中。它说:System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies()。并且引用包含我的Initialize类的程序集。 – Joop 2010-06-21 08:49:32

+0

不要让太多的内部方法的名称:)在这里,它的意思是它为每个引用的程序集查找Init方法。但是对于一个给定的装配体,它只能看到该装配体本身。这是一个delibarate检查,我们添加了这个检查来防止程序集导致调用另一个程序集中不相关的代码。我们遵循的逻辑基本上就是我上面所写的,所以相同的程序集检查是完全故意的。 – 2010-06-21 21:09:34

0

我复制了你的代码,它完美地工作。所以尽量清理并重建整个应用程序。

你确定你不在嵌套的命名空间或什么东西?

+0

我的web应用程序的命名空间的WebApplication这是总是这样对我。 Refresher的名称空间是WebApplication.Logic。这应该没有什么区别,对吧? – Joop 2010-05-21 09:45:11

+0

我确实清理并重建了我的整个解决方案。我在我的开发机器上运行它。 Windows XP与IIS 5.1。但是因为它的目标是.NET 4.0,所以也不应该有所作为。 – Joop 2010-05-21 09:46:11

+0

如果您尝试使用内置的网络服务器(Casini) – Snake 2010-05-21 11:28:42

3

我有一个类似的问题。我在一个不同的程序集中引用了一个类。

所以在我的web应用程序中,我创建了一个包装器,它在独立的程序集中调用方法。然后,我在PreApplicationStartMethod属性中引用此包装器。

2

步骤1: 确保您已在AssemblyInfo.cs中

第2步使用的System.Web:

您还需要右键点击你的项目“添加 - >引用”,然后选择组件 - - >框架 - >点击“System.Web”。

创建类库时,创建一个项目时,它不会默认这个命名空间..

+0

感谢这帮了我 – 2015-02-22 15:08:43

+0

感谢添加参考帮助。 – Feru 2018-01-18 15:55:53