6

.NET 4(.5)には、この驚くべき機能がありますAttributePreApplicationStartMethodAttribute、SharePoint 2013で使用したいのでapp_start、ファイル内のメソッドをglobal.asax直接編集する必要はありません。

SP2013は正しいバージョンの.NETを実行しているので、この属性は正しく機能すると思いました...しかし、そうではないようです。

誰かがそれを使用する方法をもう理解しましたか?またはそれが機能しない理由を説明しますか?

小さな更新PreApplicationStartMethodAttribute:system.web dllで、次のクラスによって呼び出されていることがわかります。

// 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;
}

SharePoint2013がasp.net4.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

この正確な手法を試した単純なASPMVCアプリを作成し、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は、1つのメソッドToString()を含むクラスClass1を備えた、実際にはベアボーンです。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");
    }
}

興味深いことが実行時に発生します。このコードを実行すると、スローされる例外は、JoeAssemblyStartクラスではなく、Class1のToStringからのものです。これは、実行時にアセンブリをロードするときにPreApplicationStartMethod属性が無視されることを意味します。これは、ASP.NETパイプラインについて考えるときに驚くことではありません。

また、ClassLibrary1をMVCプロジェクトに明示的に追加し、動的にロードしなかったときに、この実験のバージョンを実行しました。この場合、PreApplicationStartMethodコードは期待どおりに呼び出されました。

要約すると、次のようになります。

  1. SharePoint 2013にコードを追加しても、SharePoint2013は再構築されません
  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ポイントをStartup属性ClassProjectに追加します。
  6. SharePointProjectの[パッケージ]/[詳細設定]に移動し、展開する必要のあるアセンブリとしてClassProjectを追加します。gacではなくWebApplicationを選択していることを確認してください。
  7. ソリューションを展開します。

このプロセスにより、ClassProjectがSharePointWebアプリケーションのbinフォルダーに展開されます。startメソッドはランタイムによって呼び出され、すべてが機能するはずです。ClassProjectをGACではなくWebApplicationにデプロイすることを確認することが重要です。

あなたがこれをしばらく遊んでいて、それがうまくいかない場合。IISはDLLをキャッシュするのが好きで、コードが呼び出されないため、[インターネット一時ファイル]の下にあるすべてのものを削除してみてください。

ああ、ClassProjectを使用する理由は、SharePointプロジェクトがGACではなくbinに展開されている場合、FeatureReceiversを使用できないためです。

于 2014-01-31T23:42:33.110 に答える
1

一部のプロジェクトには「PreApplicationStartup」がないことに気付きました。これをコンソールアプリケーションで使用すると、Webサイトでは正常に機能しましたが、同様の問題が発生しました。

実行しているメソッドが静的メソッドではない可能性もあります。

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 に答える
1

私はいくつかのアプローチを試しました-それを機能させる唯一の方法はhttpmoduleを使用することでした:http://melcher.it/2012/12/signalr-in-sharepoint-2013-the-real-time-web-is-coming/

PreApplicationStartが機能しない理由は、global.asaxがHttpApplicationではなくSPHttpApplicationを継承しているためだと思います。つまり、ソースを調べる時間がありませんでした。

長い間、マックス

于 2013-02-12T08:10:51.717 に答える