Sharepoint 2010 /検索アラートのカスタマイズ

IAlertNotifyHandlerを使用して、Sharepoint 2010で検索アラートをカスタマイズした経験についてお話したいと思います。



最初は、タスクは簡単に思えました。 すべてがシンプルなようです。 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.頭を突っ込んで、標準ソリューションを使用するとき、情報の一部がまだ私たちに届いているので、それから始められると思いました。 そして、私はおそらく最もエレガントではなく、実用的なソリューションを見つけました。





すべてのコードを完全に提供するわけではありません(長い)-要点のみです。



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を完了すると、ユーザーは、たとえばこのフォームで検索アラートを受信します。







すべて、問題は解決しました。 私はインターネットで他の方法を見つけなかったので、私の解決策が誰かを助けてくれたら嬉しいです。



All Articles