2010-05-21 122 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