手順 2 : カスタム検索 Web パーツにコードを追加する

このウォークスルーで説明するカスタム検索 Web パーツは、ユーザー入力に基づいて SQL 構文検索クエリを構築し、それを エンタープライズ検索 コンポーネントに送信します。次に、Web パーツは、検索結果を XML に変換し、XSLT 変換を適用してそれをブラウザに表示します。

手順 2 では、Web パーツに追加する必要があるコードについて説明します。

注意

XSLT 変換は、「手順 3 : XSLT 変換コードの作成」で扱います。

SearchProducts の既定のコードを変更するには

  1. SearchProducts.cs. のコードの先頭付近に次の名前空間ディレクティブを追加します。

    using System.Web.UI.WebControls.WebParts;
    using Microsoft.Office.Server.Search.Query;
    using Microsoft.SharePoint;
    using System.Data;
    using System.Xml;
    using System.Xml.Xsl;
    using System.IO;
    
  2. 次のコード行で、WebControl を System.Web.UI.WebControls.WebParts.WebPart に置き換えます。

    public class SearchProducts : WebControl
    
  3. SearchProducts のクラス宣言の上に次のコード行を追加します。

    [XmlRoot(Namespace = "SearchBDCWebPart")]
    

これで、検索コンポーネントのクエリを実行し、Web パーツのコンテンツをレンダリングするコードを記述する準備ができました。

Web パーツの子コントロールを追加し、それらをレンダリングするには

  1. クラス宣言の下に次のコードを追加します。

    Table table;
    Label lblID;
    TextBox txtID;
    CompareValidator checkID;
    Label lblName;
    TextBox txtName;
    Button cmdSearch;
    Label lblResults;
    Xml xmlResults;
    Panel xmlPanel;
    
  2. 次のコードを使用して、CreateChildControls メソッドを上書きします。

    protected override void CreateChildControls()
    {
        Controls.Clear();
    //Create a table control to use for positioning the controls
        table = new Table();
        table.Width = Unit.Percentage(100);
        for(int i =0; i<5; i++)
        {
            TableRow row= new TableRow();
            TableCell cell = new TableCell();
            row.Cells.Add(cell);
            table.Rows.Add(row);
        }
    //Create the controls for ProductID input
        lblID = new Label();
        lblID.Text = "Product ID is:";
        lblID.Width = Unit.Pixel(150);
        txtID = new TextBox();
        txtID.ID = "txtID";
    /*
    The CompareValidator control is used here to validate
    that the value entered for ProductID is an integer 
    */
        checkID = new CompareValidator();
        checkID.ControlToValidate = "txtID";
        checkID.Operator = ValidationCompareOperator.DataTypeCheck;
        checkID.Type = ValidationDataType.Integer;
        checkID.Text = "ProductID must be an integer.";
    //Add the controls for the ProductID to the table
        table.Rows[0].Cells[0].Controls.Add(lblID);
        table.Rows[0].Cells[0].Controls.Add(txtID);
        table.Rows[0].Cells[0].Controls.Add(checkID);
        table.Rows[0].Cells[0].Height = Unit.Pixel(40);
    //Create the controls for Product Name input.           
        lblName = new Label();
        lblName.Text = "Product Name contains:";
        txtName = new TextBox();
    //Add the controls for the Product Name to the table
        table.Rows[1].Cells[0].Controls.Add(lblName);
        table.Rows[1].Cells[0].Controls.Add(txtName);
        table.Rows[1].Cells[0].Height = Unit.Pixel(40);
    //Create the search button and add to the table control
        cmdSearch = new Button();
        cmdSearch.Click += new EventHandler(cmdSearch_Click);
        cmdSearch.Text = "Search Products";
        table.Rows[3].Cells[0].Controls.Add(cmdSearch);
        table.Rows[3].Cells[0].Height = Unit.Pixel(40);
    //Create a label to display the search message
        lblResults = new Label();
        table.Rows[4].Cells[0].Controls.Add(lblResults);
        table.Rows[4].Cells[0].Height = Unit.Pixel(40);
    //Add the table to the controls collection 
    }
    
  3. 次のコードを使用して、cmdSearch にクリック イベントを追加します。

    void cmdSearch_Click(object sender, EventArgs e)
    {
        string strName = txtName.Text;
        string strID = txtID.Text;
    /*
    Validate that the user entered something.
    If not, prompt the user to enter an ID or search term.
    */    
        if (strName == "" & strID == "")
        {
            lblResults.Text = "You must enter a Product ID or a Product name term for the Product Search.";
        }
        else
        {
            returnResults(buildSQL(strName, strID));   
        }
    }
    

これで、エンタープライズ検索の SQL 構文のリファレンスを使用して検索クエリ テキストを構築するコードを追加する準備ができました。

フルテキスト検索クエリを構築するには

  • 次のコードを ProductSearch クラスに追加します。

    private string buildSQL(string stName, string stID)
    {
    //This is the scope ID for the AdventureWorks 
    //Business Data Catalog application
        string BDCscopeID = "4";
    //Use the StringBuilder class for the syntax string
        StringBuilder sbSQL = new StringBuilder();
        sbSQL.Append("SELECT ProductName,ProductID,ProductNumber,Path FROM SCOPE() WHERE scope='");
        sbSQL.Append(BDCscopeID);
        sbSQL.Append("'");
        if (stName != "")
        {
            sbSQL.Append(" AND CONTAINS(ProductName,'");
            sbSQL.Append(stName);
            sbSQL.Append("')");
        }
        if (stID != "")
        {
            sbSQL.Append(" AND ProductID=");
            sbSQL.Append(stID);
        }
        return sbSQL.ToString();
    }
    

これで、クエリ オブジェクト モデルにアクセスするコードを追加する準備ができました。このコード サンプルは、Microsoft.Office.Server.Search.Query.FullTextSqlQuery クラスを使用して検索クエリを実行し、パラメータ値として SPSite オブジェクトを渡します。

サンプルでは、DataSet クラスの WriteXml メソッドを使用して、XML 形式の結果にアクセスします。結果の XML は、主要な検索結果 Web パーツからの XSLT 変換の修正版を使用して、XML を変換する XML Web コントロールに渡されます。

フルテキスト検索クエリを実行するには

  • 次のコードを ProductSearch クラスに追加します。

    private void returnResults(string strSQL)
    {
        try
        {
    /*
    Create the XML control to use for displaying the results, and the Panel
    control to use as a container for the XML control.
    */   
            xmlPanel = new Panel();
            xmlResults = new Xml();
            xmlPanel.Controls.Add(xmlResults);
            Controls.Add(xmlPanel);
            HttpContext context = HttpContext.Current;
    //Specify the path for the XSL        
            string path = context.Request.MapPath("/_layouts/productXSL.xsl");
    
    //Replace <siteName> with the name of your site    
            string sPath = "http://<siteName>";
            FullTextSqlQuery sqlQuery = new FullTextSqlQuery(new SPSite(sPath));
    //Specify result type to return 
            sqlQuery.ResultTypes = ResultType.RelevantResults;
    //Specify the full text search query string
            sqlQuery.QueryText = strSQL;
    //Return the search results to a ResultTableCollection        
            ResultTableCollection results = sqlQuery.Execute();
    //Create a ResultTable for the relevant results table
            ResultTable relResults = results[ResultType.RelevantResults];
    
    //Count the number of rows in the table; 0 = no search results        
            int x = relResults.RowCount;
            if (x !=0)
            {
                lblResults.Text = x.ToString();
                DataTable dtresults = new DataTable();
                dtresults.TableName = "Result";
                dtresults.Load(relResults, LoadOption.OverwriteChanges);
                StringWriter writer = new StringWriter();
                DataSet ds = new DataSet("All_Results");
                ds.Tables.Add(dtresults);
                ds.WriteXml(writer, XmlWriteMode.IgnoreSchema);
                XmlDocument doc = new XmlDocument();
                doc.LoadXml(writer.ToString());
                XslTransform trans = new XslTransform();
                trans.Load(path);
                xmlResults.Document = doc;
                xmlResults.Transform = trans;
            }
            else
            {
    //Send XML for an empty result set to the XML control         
                XmlDocument doc = new XmlDocument();
                doc.LoadXml("<All_Results></All_Results>");
                XslTransform trans = new XslTransform();
                trans.Load(path);
                xmlResults.Document = doc;
                xmlResults.Transform = trans;
            }
        }
        catch (Exception ex1)
        {
            lblResults.Text = ex1.ToString();
        }
    }
    

サンプル : AdventureWorks 検索 Web パーツ クラスのサンプル コード」で、SearchProducts クラスのサンプルの完全なコードを確認できます。

See Also

タスク

[ウォークスルー] AdventureWorks ビジネス データ アプリケーション サンプル用の ASP.NET Web パーツを作成する

手順 1 : カスタム検索 Web パーツのプロジェクトを設定する

手順 3 : XSLT 変換コードの作成

手順 4: カスタム検索 Web パーツの展開

手順 5: 検索 BDC Web パーツをテストする