最初は、タスクは簡単に思えました。 すべてがシンプルなようです。 MSDNドキュメントには、プロセス自体を説明する記事があり、他のリソースの例があります。 しかし、判明したように、 検索アラートを除くすべての種類のアラートのカスタマイズは、至る所で説明されています。 インターネット全体で解決策を見つけていないので、自分で解決策を提示しています(最適ではないかもしれませんが、機能しています)。
状態
Business Connectivity Services(BCS)およびEnterprise Searchを使用してSharepointを実装するSQLデータベースの検索があります。 ユーザーSharepointへの検索結果の出力は、適切なXSLT変換を使用してカスタマイズされます。 したがって、ユーザーは、検索時に、ほぼこの形式で結果を取得します(ベースは機能しています-以降、名前とすべて取り消し線が付いています)。
Sharepointを使用すると、ユーザーはデータベースに変更が加えられたときにトリガーされる各検索クエリにアラートを割り当てることができます。 トリガーされると、ユーザーは次のような電子メールを受け取ります。
つまり、標準アラートはXSLT変換を考慮せず、ユーザーに読み取り不可能な情報を提供します。 したがって、タスクを作成するときに、できれば検索時と同じように、電子メールテキストを読み取り可能なテキストに変換する必要があります。
標準アラートカスタマイズソリューション
最初に、 検索アラートに適していない標準ソリューションについて簡単に説明しますが、バージョンの起動にはその一部(段落2、5〜11)が必要になります。
1. OnAlificationメソッドでIAlertNotifyHandlerインターフェイスを実装するクラスClass1でAlertHandler dllを作成します。OnNotificationメソッドでは、現在のアラートテキストを取得し、それに応じて変更できます。
2. GACにdllを配置します
3. C:\ Program Files \ Common Files \ Microsoft Shared \ Web Server Extensions \ 14 \ TEMPLATE \ XMLにあるalertTemplates.xmlファイルのコピーを作成します。 この場合、元のファイルではなく、常にファイルのコピーを変更します(これは重要です。後で混乱することなく、標準のハンドラに戻ることができるようにするためです)。
4.新しいファイルに名前を付け(alertTemplates.xmlをコピー)、CustomAlertTemplatesを保存します。 ファイルを次のように変更します。 プロパティブロックを見つけて、このブロックに次の行を追加します。
< NotificationHandlerAssembly > AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d59ecf2a3bd66904 </ NotificationHandlerAssembly >
< NotificationHandlerClassName > AlertHandler.Class1 </ NotificationHandlerClassName >
< NotificationHandlerProperties ></ NotificationHandlerProperties >
* This source code was highlighted with Source Code Highlighter .
これで、ブロック全体が次のようになります。
< Properties >
< ImmediateNotificationExcludedFields > ID;Author;Editor;Modified_x0020_By;Created_x0020_By;_UIVersionString;ContentType;TaskGroup;IsCurrent;Attachments;NumComments; </ ImmediateNotificationExcludedFields >
< DigestNotificationExcludedFields > ID;Author;Editor;Modified_x0020_By;Created_x0020_By;_UIVersionString;ContentType;TaskGroup;IsCurrent;Attachments;NumComments; </ DigestNotificationExcludedFields >
< NotificationHandlerAssembly > AlertHandler, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d59ecf2a3bd66904 </ NotificationHandlerAssembly >
< NotificationHandlerClassName > AlertHandler.Class1 </ NotificationHandlerClassName >
< NotificationHandlerProperties ></ NotificationHandlerProperties >
</ Properties >
* This source code was highlighted with Source Code Highlighter .
注:PublicKeyTokenは、C:\ windows \ assemblyで見つけることにより、dllプロパティで表示できます。
5. C:\ Program Files \ Common Files \ Microsoft Shared \ web server extensions \ 14 \ BINからコマンドを実行します:stsadm -o updatealerttemplates -filename "C:\ Program Files \ Common Files \ Microsoft Shared \ Web Server Extensions \ 14 \ TEMPLATE \ XML \ customalerttemplates.xml "-url 6.次のコマンドを実行します:stsadm -o setproperty -pn job-immediate-alerts -pv" every 1 minutes "これはテスト専用です。 テスト後に戻ります。
7. SharePointが送信メールを送信するように構成されていることを確認します。
8.ドキュメントライブラリでテストする場合は、ドキュメントライブラリなどでアラートがオンになっていることを確認します。
9.コマンドiisresetを実行します
10.コマンドservices.mscを実行します
11. Windows SharePoint Servicesタイマーを再起動します。
標準ソリューションの問題
すべてが素晴らしい、すべてが機能しますが、検索アラートの場合はそうではありません。 OnNotificationメソッド(SPAlertHandlerParams ahp)の検索アラートの場合、カスタマイズに実際に必要なahp.eventDataおよびahp.bodyフィールドの値は取得されません。
social.technet.microsoft.comフォーラムでの質問に答えて、次の情報を受け取りました。
まず、次のようにIAlertNotifyHandlerを使用してSharePointアラートをカスタマイズできます。
blogs.msdn.com/b/sharepointdeveloperdocs/archive/2007/12/14/how-to-customizing-alert-emails-using-ialertnotificationhandler.aspx
第二に、変更するための検索アラートメールテンプレートはありません。
すべてのアラートテンプレート: msdn.microsoft.com/en-us/library/bb802738.aspx
つまり、解決策はないことがわかりました!! ..しかし、私は戦いなしでwithoutめることに慣れていなかったため、インターネットから少しずつ情報を収集し続けました。 そして、これはそれから来たものです。
私のオプション
1.フォーラムを読むと、検索アラートを処理するには、まず新しいタイプのAlertTemplate-「OSS.Search」を追加する必要があることがわかりました。 CustomAlertTemplatesファイルに追加します。
< AlertTemplate Type ="Custom" Name ="OSS.Search" AlwaysNotify ="True" DefaultTitle ="Search" >
< EventTypes IsVisible ="True" >
< EventType Mask ="0x1" Selected ="true" > $Resources:Microsoft.Office.Server.Search,SearchResults_ATEventDiscovered; </ EventType >
< EventType Mask ="0x2" > $Resources:Microsoft.Office.Server.Search,SearchResults_ATEventModified; </ EventType >
< EventType Mask ="0x3" > $Resources:Microsoft.Office.Server.Search,SearchResults_ATEventAll; </ EventType >
</ EventTypes >
< Frequency IsVisible ="true" ShowImmediate ="false" ShowDaily ="true" ShowWeekly ="true" ShowTime ="false" DefaultFrequency ="Daily" />
< Filters IsVisible ="false" />
< Properties >
< NotificationHandlerAssembly > mySearchAlert, Version=1.0.0.0, Culture=neutral, PublicKeyToken=aa1e89f3cc0ef56b </ NotificationHandlerAssembly >
< NotificationHandlerClassName > mySearchAlert.MySearchAlertHandler </ NotificationHandlerClassName >
< NotificationHandlerProperties ></ NotificationHandlerProperties >
< UpdateHandlerAssembly > mySearchAlert, Version=1.0.0.0, Culture=neutral, PublicKeyToken=aa1e89f3cc0ef56b </ UpdateHandlerAssembly >
< UpdateHandlerClassName > mySearchAlert.MySearchUpdateAlertHandler </ UpdateHandlerClassName >
< UpdateHandlerProperties ></ UpdateHandlerProperties >
</ Properties >
</ AlertTemplate >
* This source code was highlighted with Source Code Highlighter .
標準ハンドラに戻るために、以前に保存された標準ファイルでは不十分であることに注意することが重要です。そのため、標準のalertTemplates.xmlをファイルにコピーします。たとえば、alertTemplates_forRestore.xmlに次のセクションを追加します
< AlertTemplate Type ="Custom" Name ="OSS.Search" AlwaysNotify ="True" DefaultTitle ="Search" >
< EventTypes IsVisible ="True" >
< EventType Mask ="0x1" Selected ="true" > $Resources:Microsoft.Office.Server.Search,SearchResults_ATEventDiscovered; </ EventType >
< EventType Mask ="0x2" > $Resources:Microsoft.Office.Server.Search,SearchResults_ATEventModified; </ EventType >
< EventType Mask ="0x3" > $Resources:Microsoft.Office.Server.Search,SearchResults_ATEventAll; </ EventType >
</ EventTypes >
< Frequency IsVisible ="true" ShowImmediate ="false" ShowDaily ="true" ShowWeekly ="true" ShowTime ="false" DefaultFrequency ="Daily" />
< Filters IsVisible ="false" />
< Properties >
< NotificationHandlerAssembly > Microsoft.Office.Server.Search, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c </ NotificationHandlerAssembly >
< NotificationHandlerClassName > Microsoft.Office.Server.Search.Query.SearchAlertHandler </ NotificationHandlerClassName >
< NotificationHandlerProperties ></ NotificationHandlerProperties >
< UpdateHandlerAssembly > Microsoft.Office.Server.Search, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c </ UpdateHandlerAssembly >
< UpdateHandlerClassName > Microsoft.Office.Server.Search.Query.SearchAlertHandler </ UpdateHandlerClassName >
< UpdateHandlerProperties ></ UpdateHandlerProperties >
</ Properties >
</ AlertTemplate >
* This source code was highlighted with Source Code Highlighter .
alertTemplates_forRestore.xmlファイルを慎重に保存します。これがないと、標準ハンドラーにロールバックできません。
2.頭を突っ込んで、標準ソリューションを使用するとき、情報の一部がまだ私たちに届いているので、それから始められると思いました。 そして、私はおそらく最もエレガントではなく、実用的なソリューションを見つけました。
- 処理されたアラートに関する情報を使用して、プログラムによって新しい一時検索アラートを作成しますSearchAlert alert2 = new SearchAlert(s1、q1);
- 処理されたアラートの検索文字列を使用して、SharePointサーバーへの検索クエリを作成します-Search.Query.Query query = alert2.CreateSearchQuery
Reflectionを使用して、クエリクエリの内部AlertInfoプロパティを設定し、LastUpdateTimeを必要な値に設定して(最後のアラートから変更されたレコードのみを取得するため)、クエリ結果を取得します - FullTextSqlQueryを使用してSQLデータベースから追加情報を取得します
- 作成したalert2を削除します
- クエリで受信したSQLデータベースフィールドとSaherepoint 2010フィールドに基づいて、本文のHTML本文テキストを生成しています。
すべてのコードを完全に提供するわけではありません(長い)-要点のみです。
public class MySearchAlertHandler : IAlertNotifyHandler
//
public bool OnNotification(SPAlertHandlerParams alertHandler)
{
...
return CustomAlertNotification(alertHandler);
...
}
public bool CustomAlertNotification(SPAlertHandlerParams alertHandlerParams)
{
string myBody = "" ;
SPSite site = null ;
int searchAlertNotificationQuota = 200;
TimeSpan span;
SPAlert a = alertHandlerParams.a;
site = new SPSite(alertHandlerParams.siteUrl+ alertHandlerParams.webUrl;);
// alertTime span
DateTime alertTime = a.AlertTime;
if (a.AlertFrequency == SPAlertFrequency.Weekly)
{
span = TimeSpan .FromDays(7.0);
}
else
{
span = TimeSpan .FromDays(1.0);
}
if ((alertTime + span) <= DateTime .Now)
{
return true ;
}
using (SPWeb web = site.OpenWeb())
{
// ( ) queryText
string queryText = Utils.GetValueFromXML(a.Properties[ "p_query" ], "QueryText" );
SPSite s1 = new SPSite (alertHandlerParams.siteUrl+alertHandlerParams.webUrl );
Query q1 = new KeywordQuery(s1);
q1.QueryText = queryText;
// alert2,
SearchAlert alert2 = new SearchAlert(s1,q1);
alert2.ChangeType = AlertChangeType.DiscoveredOrModified;
alert2.InnerAlert.AlertFrequency = alertHandlerParams.a.AlertFrequency ;
alert2.InnerAlert.Title = "Temp#1" ;
alert2.InnerAlert.EventType = alertHandlerParams.a.EventType;
alert2.InnerAlert.User = s1.OpenWeb().CurrentUser ;
alert2.InnerAlert.AlertType = alertHandlerParams.a.AlertType;
alert2.Update();
// query alert2 queryText
using (Microsoft.Office.Server.Search.Query.Query query = alert2.CreateSearchQuery ())
{
ResultTableCollection tables;
query.QueryText = queryText;
query.RowLimit = searchAlertNotificationQuota;
query.TrimDuplicates = false ;
// , , , .
, Reflection internal AlertInfo query, LastUpdateTime
AlertInfo ai = new AlertInfo();
ai.ChangeType = alert2.ChangeType;
ai.LastUpdateTime = alertTime - span;
Type t1 = query.GetType();
if (t1.GetProperty( "AlertInfo" , System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance) == null )
throw new ArgumentOutOfRangeException( "propName" , string .Format( "Property {0} was not found in Type {1}" ,
"AlertInfo" , query.GetType().FullName));
t1.InvokeMember( "AlertInfo" , System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.SetProperty |
System.Reflection.BindingFlags.Instance, null , query, new object [] { ai });
// query
ResultTable result = null ;
try
{
tables = query.Execute();
}
catch
{
alert2.Delete();
return false ;
}
result = tables[ResultType.RelevantResults];
// result - alert2 -
alert2.Delete();
// DataTable . - WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL
// DiscoveredTime
System.Data.DataTable myTable = new System.Data.DataTable();
myTable.Load(result2, System.Data.LoadOption.OverwriteChanges);
foreach (System.Data.DataRow myrow in myTable.Rows)
{
if ( Convert .ToDateTime(myrow[ "DiscoveredTime" ]) > alertTime - span)
{
//
}
else
{
//
}
}
// , SQL, FullTextSqlQuery
FullTextSqlQuery fts = new FullTextSqlQuery(site2);
fts.QueryText = "SELECT WorkId, Rank, Title, Author, Size, Path, Description, Write, SiteName, CollapsingStatus, HitHighlightedSummary, HitHighlightedProperties, ContentClass, IsDocument, PictureThumbnailURL, PopularSocialTags, PictureWidth, PictureHeight, DatePictureTaken, ServerRedirectedURL, ErgebnisKenntnis, LetzterKontakt, Kandidatenmail FROM SCOPE() WHERE Path='" + myrow[ "Path" ].ToString() + "'" ;
fts.ResultTypes = ResultType.RelevantResults;
fts.RowLimit = 300;
ResultTableCollection rtc = fts.Execute();
* This source code was highlighted with Source Code Highlighter .
ここで、ErgebnisKenntnis、LetzterKontakt、KandidatenmailはSQLデータベースのフィールドです(例のみ表示)。 それらを検索できるようにするには、これらのフィールドがSharepoint 2010サーバーのメタデータプロパティに登録されていることが重要です。
これで、SQLデータベースの任意のフィールドSharepointを使用してmyBodyメッセージのHTML本文を形成でき、最後にユーザーに送信することを忘れないでください。
SPUtility.SendEmail(web, false , false , string .Format( "{0}" , alertHandlerParams.headers[ "To" ]),
string .Format( "{0}" , alertHandlerParams.headers[ "Subject" ]), myBody);
* This source code was highlighted with Source Code Highlighter .
これで、標準ソリューションの段落2、5〜11を完了すると、ユーザーは、たとえばこのフォームで検索アラートを受信します。
すべて、問題は解決しました。 私はインターネットで他の方法を見つけなかったので、私の解決策が誰かを助けてくれたら嬉しいです。