步骤 2:为自定义搜索 Web 部件添加代码
此演练中介绍的自定义搜索 Web 部件基于用户输入构造 SQL 语法搜索查询,并将其提交给企业级搜索组件。然后,Web 部件将搜索结果转换为 XML,并应用 XSLT 转换将结果显示在浏览器中。
步骤 2 介绍您必须为 Web 部件添加的代码。
备注
XSLT 转换在步骤 3:创建 XSLT 转换代码中进行介绍。
修改 SearchProducts 中的默认代码
将以下命名空间指令添加在 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;
在以下代码行中,用 System.Web.UI.WebControls.WebParts.WebPart 替换 WebControl。
public class SearchProducts : WebControl
将以下代码行添加在 SearchProducts 的类声明上方。
[XmlRoot(Namespace = "SearchBDCWebPart")]
您现在可以编写代码以查询搜索组件,然后呈现 Web 部件的内容。
添加 Web 部件的子控件并呈现这些子控件
将以下代码添加在类声明下方。
Table table; Label lblID; TextBox txtID; CompareValidator checkID; Label lblName; TextBox txtName; Button cmdSearch; Label lblResults; Xml xmlResults; Panel xmlPanel;
通过使用以下代码重写 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 }
使用以下代码为 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 类示例的完整代码。