步骤 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. 在以下代码行中,用 System.Web.UI.WebControls.WebParts.WebPart 替换 WebControl。

    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 传递给转换 XML 的 XML Web 控件,该控件使用核心搜索结果 Web 部件的 XSLT 转换修改版本进行转换。

执行全文搜索查询

  • 将下面的代码添加到 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 部件