6

在 .NET 4(.5) 中有这个惊人的Attribute: PreApplicationStartMethodAttribute,我想在 SharePoint 2013 中使用它,所以我不必直接编辑文件app_start中的方法global.asax

由于 SP2013 运行正确版本的 .NET,我认为该属性可以正常工作……但情况似乎并非如此。

有没有人知道如何使用它?或解释为什么它不能工作?

小更新:在 system.web dll 中我可以看到PreApplicationStartMethodAttribute由以下类调用。

// System.Web.Compilation.BuildManager
internal static ICollection<MethodInfo> GetPreStartInitMethodsFromAssemblyCollection(IEnumerable<Assembly> assemblies, bool buildingFromCache)
{
    List<MethodInfo> list = new List<MethodInfo>();
    foreach (Assembly current in assemblies)
    {
        PreApplicationStartMethodAttribute[] array = null;
        try
        {
            array = (PreApplicationStartMethodAttribute[])current.GetCustomAttributes(typeof(PreApplicationStartMethodAttribute), true);
        }
        catch
        {
        }
        if (array == null || !array.Any<PreApplicationStartMethodAttribute>())
        {
            if (buildingFromCache)
            {
                return null;
            }
        }
        else
        {
            PreApplicationStartMethodAttribute[] array2 = array;
            for (int i = 0; i < array2.Length; i++)
            {
                PreApplicationStartMethodAttribute preApplicationStartMethodAttribute = array2[i];
                MethodInfo methodInfo = null;
                if (preApplicationStartMethodAttribute.Type != null && !string.IsNullOrEmpty(preApplicationStartMethodAttribute.MethodName) && preApplicationStartMethodAttribute.Type.Assembly == current)
                {
                    methodInfo = BuildManager.FindPreStartInitMethod(preApplicationStartMethodAttribute.Type, preApplicationStartMethodAttribute.MethodName);
                }
                if (!(methodInfo != null))
                {
                    throw new HttpException(SR.GetString("Invalid_PreApplicationStartMethodAttribute_value", new object[]
                    {
                        current.FullName,
                        (preApplicationStartMethodAttribute.Type != null) ? preApplicationStartMethodAttribute.Type.FullName : string.Empty,
                        preApplicationStartMethodAttribute.MethodName
                    }));
                }
                list.Add(methodInfo);
            }
        }
    }
    return list;
}

如果 SharePoint 2013 在 asp.net 4.0 上运行,我可能会幸运地在应用程序上调用以下内容。

C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_compiler.exe
4

4 回答 4

2

以下只是推测,但基于实验。

我认为 SharePoint 2013 使用某种运行时程序集加载来加载任何和所有自定义代码程序集。毕竟,当我们添加 WebPart 时,应用程序不会重新编译。此处描述了如何完成此操作的简单方法:http: //msdn.microsoft.com/en-us/library/d133hta4.aspx

我创建了一个简单的 ASP MVC 应用程序,并在其中尝试了这种精确的技术,并在我的 global.asax 中加载了一个程序集:

 protected void Application_Start()
    {
        ObjectHandle handle = Activator.CreateInstance("ClassLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=27b9c31f70a4bee3", "ClassLibrary1.Class1");
        Object p = handle.Unwrap();
        Type t = p.GetType();

        MethodInfo method = t.GetMethod("ToString");
        Object retVal = method.Invoke(p, null);
    }

正在加载的程序集是我创建并放置在 GAC 中的。这个 ClassLibrary1 是真正的准系统,类 Class1 包含一个方法 ToString()。ToString 方法抛出异常,很容易看出它是否被调用:

public class Class1
{
    public override string ToString()
    {
        throw new ApplicationException("Joe was in the tostring");
        return base.ToString();
    }
}

程序集还使用 AssemblyInfo.cs 文件中的 PreApplicationStartMethod:

[assembly: PreApplicationStartMethod(typeof(ClassLibrary1.JoeAssemblyStart), "Start")]

最后有一个由 PreApplicationStartMethod 属性调用的简单类:

 public class JoeAssemblyStart
{
    public static void Start()
    {
        throw new ApplicationException("joe was here in this assembly start");
    }
}

有趣的事情发生在运行时。当我运行此代码时,引发的异常来自 Class1 中的 ToString,而不是 JoeAssemblyStart 类。这意味着当我们在运行时加载程序集时会忽略 PreApplicationStartMethod 属性,这在考虑 ASP.NET 管道时并不奇怪。

当我将 ClassLibrary1 显式添加到我的 MVC 项目中并且没有动态加载它时,我还运行了这个实验的一个版本。在这种情况下,PreApplicationStartMethod 代码按预期调用。

所以总结一下:

  1. 向 SharePoint 2013 添加代码时不会重建它
  2. 因此,您的代码必须以某种动态方式加载
  3. 动态加载的程序集不能早在 PreApplicationStartMethod 时影响 ASP.NET 管道
于 2013-04-17T11:03:56.057 回答
2

这有点晚了,但我认为这很重要。

PreApplicationStartMethod 属性在 SharePoint 2013 中运行良好。但是,需要将程序集部署到 bin 文件夹。

脚步

  1. 创建您的普通 SharePoint 解决方案(我们称之为 SharePointProject)。
  2. 创建一个新的类库项目并为其命名。(让我们称之为ClassProject)
  3. 将代码添加一个名为 Startup 的新类到 ClassProject。
  4. 添加一个名为 Start to Startup 的静态方法并执行您的启动工作。
  5. 将 PreApplicationStartMethod 指向 ClassProject 的 Startup 属性。
  6. 转到 SharePointProject 中的包/高级设置,并将 ClassProject 添加为需要部署的程序集。确保选择 WebApplication 而不是 gac。
  7. 部署您的解决方案。

此过程会将 ClassProject 部署到 SharePoint Web 应用程序的 bin 文件夹。start 方法将由运行时调用,一切都应该正常工作。确保将 ClassProject 部署到 WebApplication 而不是 GAC 很重要。

如果你一直在玩这个,它不起作用。尝试删除 Temporary Internet Files 下的所有内容,因为 IIS 喜欢缓存 Dll,您的代码将不会被调用。

哦,使用 ClassProject 的原因是因为如果将 SharePoint 项目部署到 bin 而不是 GAC,则无法使用功能接收器。

于 2014-01-31T23:42:33.110 回答
1

我尝试了几种方法 - 我让它工作的唯一方法是使用 httpmodule:http: //melcher.it/2012/12/signalr-in-sharepoint-2013-the-real-time-web-is-coming/

我认为 PreApplicationStart 不起作用的原因是 global.asax 继承了 SPHttpApplication 而不是 HttpApplication - 没有时间去查看源代码。

久违了,麦克斯

于 2013-02-12T08:10:51.717 回答
1

我注意到有些项目没有“PreApplicationStartup”,我在控制台应用程序上使用它时遇到了类似的问题,尽管它在网站上运行良好。

也可能是您正在运行的方法不是静态方法。

public class PreApplicationStart
    {
        public static void Start()
        {
            // Pre application startup configuration goes here
        }
    }

在 AssemblyInfo.cs 中添加以下内容

[assembly: PreApplicationStartMethod(typeof(PreApplicationStart), "Start")]
于 2013-01-31T15:45:09.013 回答