演练:创建带有其他内容的网站定义

本演练演示如何创建一个功能更全面的网站定义,其中包含您可能会向网站定义中添加的多个元素。 它是一个雇员定位器网站定义,可供您用来在 Bing 地图上根据某个雇员的姓名及其工作国家/地区找到该雇员。

本演练将演示以下任务:

  • 使用 Visual Studio 项目模板创建一个网站定义。

  • 在解决方案中添加和包含一个自定义母版页。

  • 向解决方案中添加一个可视 Web 部件。

  • 向解决方案中添加自定义字段。

  • 添加一个包含自定义字段的内容类型。

  • 添加一个基于内容类型的列表定义。

  • 为与网站定义一起部署的列表添加一个列表实例和默认数据。

  • 通过向网站的 default.aspx 页中添加一个可视 Web 部件来自定义该页。

  • 在可视 Web 部件上自定义一个用户控件。

  • 向解决方案中添加一个在可视 Web 部件上显示的自定义徽标图像。

提示

对于在以下说明中使用的某些 Visual Studio 用户界面元素,您的计算机可能会显示不同的名称或位置。这些元素取决于您所使用的 Visual Studio 版本和您所使用的设置。有关更多信息,请参见 Visual Studio 设置

系统必备

您需要以下组件来完成本演练:

  • 支持的 Microsoft Windows 和 SharePoint 版本。 有关更多信息,请参见 开发 SharePoint 解决方案的要求.

  • SharePoint Designer 2010。

  • Visual Studio 2010.

  • Bing 地图平台开发人员帐户凭据。 您可在 Bing Maps Account Center(Bing 地图帐户中心)注册一个免费的开发人员帐户。

创建网站定义解决方案

首先,在 Visual Studio 中创建网站定义项目。

创建网站定义项目

  1. 通过指向**“文件”菜单上的“新建”并单击“项目”,显示“新建项目”**对话框。

  2. 展开**“Visual C#”“Visual Basic”下的“SharePoint”节点,然后单击“2010”**。

  3. 在“模板”窗格中选择**“网站定义”**。

  4. 在**“名称”框中,键入 Testsitedef2,然后单击“确定”**。

    这将显示**“SharePoint 自定义向导”**。

  5. 在**“指定用于调试的网站和安全级别”**页上,输入要在其中调试网站定义的 SharePoint Server 网站的 URL,或者使用默认位置 (http://系统名称/)。

  6. 在**“此 SharePoint 解决方案的信任级别是什么?”部分,使用默认值“部署为场解决方案”**。

    所有网站定义项目都必须部署为场解决方案。 有关沙盒化解决方案与场解决方案的更多信息,请参见沙盒解决方案注意事项

  7. 单击**“完成”。 该项目将显示在“解决方案资源管理器”**中。

添加徽标图像

接下来,向解决方案中添加一个图像以用作网站定义中的公司徽标。

添加图像

  1. 在**“解决方案资源管理器”中右击项目节点,指向“添加”,然后单击“SharePoint‘Images’映射文件夹”**。

    由于**“Images”**文件夹会直接映射到 SharePoint 文件系统,因此向该文件夹中添加的文件会部署到 SharePoint /images 文件夹并可在 SharePoint 中使用。

  2. 在**“Images”下右击“TestSiteDef2”文件夹,指向“添加”,然后单击“现有项”。 选择要用作徽标的图像文件,然后单击“添加”**。

    或者,还可以单击快捷菜单上的**“新建项”**并创建一个新图像,只不过可选的图像类型有限。 通常,最好是使用其他工具来创建图像。

  3. 若要向解决方案中添加其他图像,请重复步骤 2。 例如,可以添加另一个图像来充当本主题后面添加的图像控件的占位符。

添加自定义母版页

如果您希望网站定义使用自定义母版页,则可以向解决方案中添加一个自定义母版页。

添加自定义母版页

  1. 创建母版页。 有关更多信息,请参见 ASP.NET 母版页

  2. 先导出自定义母版页,然后将其导入 Visual Studio 中,如演练:导入带有图像的自定义母版页和网站页中所述。

  3. 向模块添加母版页。 若要执行此操作,请在**“解决方案资源管理器”中右击项目节点,指向“添加”,然后单击“新建项”**。

  4. 在**“添加新项”对话框的 SharePoint 模板列表中,选择“模块”**。 为该模块指定名称。

  5. 在模块中,删除默认的 Sample.txt 文件。

  6. 向模块添加一个名为 _catalogs 的文件夹,然后在该文件夹下添加一个名为 masterpage 的文件夹。

    这将与 SharePoint 中其他母版页的文件位置匹配。

  7. 在**“masterpage”文件夹下添加母版页。 为此,请选择模块节点,然后在“项目”菜单上单击“添加现有项”**。 找到该母版页并将其选中。 母版页文件的文件扩展名为 .master。

  8. 将母版页的**“部署冲突解决方法”设置更改为“自动”**。

  9. 在模块中双击 Elements.xml 以在 XML 设计器中将其打开。

    必须更新 Elements.xml 文件以引用母版页。

  10. 将现有模块标记替换为以下标记。

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="https://schemas.microsoft.com/sharepoint/">
        <Module Name="[Module Name]" 
                Url="_catalogs/masterpage">
            <File Path="[Module Name]\_catalogs\masterpage\[Master Page 
              Name].master" 
                  Url="[Master Page Name].master" 
                  Type="GhostableInLibrary" />
        </Module>
    </Elements>
    

    确保将占位符值替换为模块和母版页的实际名称。

  11. 在 default.aspx 文件中更改母版页的名称。 例如,如果母版页的名称为“newmaster.master”,您将使用以下内容。

    <%@ Page language="C#" MasterPageFile="~/_catalogs/masterpage/newmaster.master" Inherits="Microsoft.SharePoint.WebPartPages.WebPartPage,Microsoft.SharePoint,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c"  %>
    
  12. 保存项目。

定义自定义字段

定义稍后用于创建自定义列表的自定义字段。 这些字段提供了网站定义中的代码所需的其他数据。

定义自定义字段

  1. 在**“解决方案资源管理器”中右击网站定义节点,指向“添加”,然后单击“新建项”**。

  2. 在模板列表中选择**“空元素”**,然后将元素命名为 SiteColumns。

  3. 在 Elements.xml 文件中,将标记替换为以下内容。

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="https://schemas.microsoft.com/sharepoint/">  
      <Field ID="{587DE9D5-618C-42C4-A754-06EA36CF7496}" 
             Type="Text" 
             Name="Latitude" 
             DisplayName="Latitude" 
             Group="Coordinates"/>
      <Field ID="{5D1CFF2C-8032-4792-AB34-8E0A0520B478}" 
             Type="Text" 
             Name="Longitude" 
             DisplayName="Longitude" 
             Group="Coordinates"/>
      <Field ID="{8B7E3CC0-40B5-465E-81FE-D63B7471B7CE}" 
             Type="Text" 
             Name="Region" 
             DisplayName="Region" 
             Group="Coordinates"/>
      <Field ID="{8A152314-DB62-4EC7-96E7-E28F8A253B1D}" 
             Type="Text" 
             Name="StaffNumber" 
             DisplayName="StaffNumber" 
             Group="Coordinates"/>
    </Elements>
    

    此标记会向 SharePoint 添加四个自定义字段:Latitude、Longitude、Region 和 StaffNumber。 这四个字段用于标识雇员及其位置。 可以根据需要添加更多字段。 使用**“工具”菜单上的“创建 GUID”**工具为每个附加字段生成一个唯一 GUID。

    提示

    如果您重新运行此解决方案,请注释掉字段定义以避免错误。

  4. 保存项目。

添加内容类型

创建引用新字段的内容类型。

添加内容类型

  1. 在**“解决方案资源管理器”中右击网站定义节点,指向“添加”,然后单击“新建项”**。

  2. 在模板列表中选择**“内容类型”**,然后将新内容类型命名为 StaffListContentType。

  3. 在**“选择内容类型设置”页上,在基联系人类型列表中选择“联系人”**。

  4. 在该内容类型的 Elements.xml 文件中,将标记替换为以下内容:

    <?xml version="1.0" encoding="utf-8"?>
    <Elements xmlns="https://schemas.microsoft.com/sharepoint/">
      <!-- Parent ContentType: Contact (0x0106) -->
      <ContentType ID="0x010600a024d6b9cf214430a254b1272eaedc4f"
                   Name="TestSiteDef2 - StaffListContentType"
                   Group="Custom Content Types"
                   Description="My Content Type"
                   Inherits="TRUE"
                   Version="0">
        <FieldRefs>
          <FieldRef ID="{587DE9D5-618C-42C4-A754-06EA36CF7496}"
                    Name="Latitude"
                    DisplayName="Latitude"/>
          <FieldRef ID="{5D1CFF2C-8032-4792-AB34-8E0A0520B478}"
                    Name="Longitude"
                    DisplayName="Longitude"/>
          <FieldRef ID="{8B7E3CC0-40B5-465E-81FE-D63B7471B7CE}"
                    Name="Region"
                    DisplayName="Region"/>
          <FieldRef ID="{8A152314-DB62-4EC7-96E7-E28F8A253B1D}"
                    Name="StaffNumber"
                    DisplayName="StaffNumber"/>
        </FieldRefs>
      </ContentType>
    </Elements>
    
  5. 保存项目。

添加列表定义

创建引用新内容类型的列表定义。

添加列表定义

  1. 在**“解决方案资源管理器”中右击网站定义节点,指向“添加”,然后单击“新建项”**。

  2. 在模板列表中选择**“基于内容类型的列表定义”**,然后该列表定义命名为 StaffListDefinition。

  3. 在**“选择列表定义设置”页上,使用显示名称和基内容类型的默认值。 清除“为此列表定义添加列表实例”框,然后单击“完成”**。

    这将使列表定义基于新内容类型。 稍后,您将在 onet.xml 文件中创建一个列表实例。

  4. 双击 Schema.xml 以打开它。 请注意,文件的顶部引用了自定义字段。

向 onet.xml 添加默认列表数据

若要在部署网站定义后,向雇员列表提供新列表定义的实例和一些默认雇员信息,请将相应数据添加到网站定义的 onet.xml 文件中。

向 onet.xml 添加列表数据

  1. 双击 onet.xml 文件以打开它。

  2. 将 <Lists/> 标记替换为以下标记。

    <Lists>
        <List Title="StaffList"
              FeatureId="fea29b33-8752-45d4-a5bd-6f7a54db7d49"
              Url="Lists/TestSiteDef2-StaffList"
              Description="" Type="10000">
              <Data>
                <Rows>
                  <Row>
                    <Field Name="FirstName">David</Field>
                    <Field Name="FullName">David Pelton</Field>
                    <Field Name="Region">Northwest</Field>
                    <Field Name="Longitude">-122.33</Field>
                    <Field Name="Latitude">47.60</Field>
                    <Field Name="StaffNumber">100200</Field>
                  </Row>
                  <Row>
                    <Field Name="FirstName">Joe</Field>
                    <Field Name="FullName">Joe Healy</Field>
                    <Field Name="Region">Southwest</Field>
                    <Field Name="Longitude">-115.13</Field>
                    <Field Name="Latitude">36.15</Field>
                    <Field Name="StaffNumber">100300</Field>
                  </Row>
                  <Row>
                    <Field Name="FirstName">Lisa</Field>
                    <Field Name="FullName">Lisa Andrews</Field>
                    <Field Name="Region">Northeast</Field>
                    <Field Name="Longitude">-73.98</Field>
                    <Field Name="Latitude">40.75</Field>
                    <Field Name="StaffNumber">100400</Field>
                  </Row>
                  <Row>
                    <Field Name="FirstName">Chris</Field>
                    <Field Name="FullName">Chris Ashton</Field>
                    <Field Name="Region">Southeast</Field>
                    <Field Name="Longitude">-84.38</Field>
                    <Field Name="Latitude">33.76</Field>
                    <Field Name="StaffNumber">100500</Field>
                  </Row>
                </Rows>
              </Data>
        </List>
    </Lists>
    
  3. 将功能的范围设置为网站级别。 为此,请在**“解决方案资源管理器”中双击功能文件以在功能设计器中将其打开。 在功能设计器中,将“范围”设置为“网站”**。

  4. 保存项目。

添加对 Bing 地图服务的引用

调用 Bing Maps Imagery 服务以提供用于显示所选雇员位置的地图。

向解决方案中添加 Bing Maps Imagery 服务

  1. 向项目添加服务引用。 为此,请在**“解决方案资源管理器”中右击项目节点,然后单击“添加服务引用”**。

  2. 在**“添加服务引用”对话框的“地址”**框中,输入以下 URL。

    http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc?wsdl
    
  3. 单击**“转到”,在“命名空间”框中键入 ImageryService,然后单击“确定”**。

  4. 从网站定义中删除 app.config 文件。

    此文件(已由服务添加)提供了必要的终结点和绑定。 但由于它无法用于 SharePoint 解决方案,因此稍后将通过代码添加其功能。

  5. Bing 地图 Web 服务要求您具有 Bing 地图密钥才能发出请求。 您可通过在 Bing Maps Account Center(Bing 地图帐户中心)上登录您的帐户来获取密钥。

创建具有控件的可视 Web 部件

接下来,创建一个具有控件的可视 Web 部件以显示在网站定义的主页上。

创建可视 Web 部件

  1. 在**“解决方案资源管理器”中右击网站定义节点,指向“添加”,然后单击“新建项”**。

  2. 在模板列表中选择**“可视 Web 部件”**,然后使用默认值 VisualWebPart1 作为 Web 部件的名称。

  3. 在 VisualWebPart1UserControl.ascx 中的现有标记下方添加以下内容。

    <style type="text/css">
        .style4
        {
            height: 205px;
            width: 187px;
        }
        .style5
        {
            height: 396px;
            width: 187px;
        }
        .style7
        {
            height: 205px;
            width: 291px;
        }
        .style8
        {
            height: 396px;
            width: 291px;
        }
        </style>
    
    <table style="width: 100%;">
        <tr>
            <td align="center" class="style4" valign="middle">
    <asp:Image ID="Image1" runat="server" Height="200px" 
        ImageUrl="~/_layouts/images/TestSiteDef2/logo.jpg" Width="350px" />
            </td>
            <td class="style7">
    <asp:Label ID="Label1" runat="server" Font-Size="XX-Large" 
        Font-Underline="True" Text="Tailspin Toys"></asp:Label>
                <br />
                <br />
    <asp:Label ID="Label7" runat="server" Font-Size="X-Large" 
        Font-Underline="False" Text="Employee Locator"></asp:Label>
            </td>
        </tr>
        <tr>
            <td class="style5" valign="top">
                <br />
    <asp:Label ID="Label2" runat="server" Font-Size="Large" Text="Region:"></asp:Label>
                <br />
                <asp:DropDownList ID="DropDownList1" runat="server" Height="24px" 
            Width="352px" onselectedindexchanged="DropDownList1_SelectedIndexChanged" 
                    AutoPostBack="True">
                <asp:ListItem>Northeast</asp:ListItem>
                <asp:ListItem>Northwest</asp:ListItem>
                <asp:ListItem>Southeast</asp:ListItem>
                <asp:ListItem>Southwest</asp:ListItem>
            </asp:DropDownList>
                <br />
                <br />
        <asp:Label ID="Label6" runat="server" Font-Size="Large" Text="Staff:"></asp:Label>
                <br />
        <asp:ListBox ID="ListBox1" runat="server" Width="352px" 
            onselectedindexchanged="ListBox1_SelectedIndexChanged" AutoPostBack="True"></asp:ListBox>
                <br />
                <br />
    &nbsp;&nbsp;
                </td>
            <td class="style8">
                <br />
    <asp:Label ID="Label5" runat="server" Font-Size="Large" Text="Map Location:"></asp:Label>
                <br />
    <asp:Image ID="Image2" runat="server" Height="388px" 
        ImageUrl="" Width="465px" />
            </td>
        </tr>    
    </table>
    
    <br />
    

    这会向页添加以下内容:一个标题、一个徽标图像、一个包含区域的下拉列表框、一个包含雇员姓名的列表框和一个显示地图的图像控件。

  4. 打开位于 VisualWebPart1UserControl.ascx 之下的文件 VisualWebPart1UserControl.ascx.cs,并将该文件的代码替换为以下代码。

    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using Microsoft.SharePoint;
    using TestSiteDef2.ImageryService;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.Text;
    
    namespace TestSiteDef2.SiteDefinition.VisualWebPart1
    {
        public partial class VisualWebPart1UserControl : UserControl
        {
            protected void Page_Load(object sender, EventArgs e)
            {
            }
    
            protected void DropDownList1_SelectedIndexChanged(object sender, EventArgs e)
            {
                string selectedRegion = DropDownList1.SelectedItem.Text;
    
                SPSite site = new SPSite(Context.Request.Url.AbsoluteUri);
                // Add the SharePoint server name below.
                string webName = 
                    Context.Request.Url.AbsoluteUri.Replace("https://localhost/", "");
                webName = webName.Replace("http://[SharePoint Server Name]/", "");
                webName = webName.Replace("/default.aspx", "");
    
                SPWeb web = site.AllWebs[webName];
                SPList list = web.Lists["StaffList"];
    
                ListBox1.Items.Clear();
                foreach (SPListItem item in list.Items)
                {
                    if (item["Region"].ToString() == selectedRegion)
                    {
                        // LinkTitle == LastName -> see schema.xml
                        ListBox1.Items.Add(item["StaffNumber"] + ": " + 
                            item["FullName"].ToString());
                    }
                }
            }
    
            protected void ListBox1_SelectedIndexChanged(object sender, EventArgs e)
            {
                // Reference the site based on its URL.
                SPSite site = new SPSite(Context.Request.Url.AbsoluteUri);
    
                // Add the SharePoint server name below.
                string webName = 
                    Context.Request.Url.AbsoluteUri.Replace("https://localhost/", "");
                webName = webName.Replace("http://[SharePoint Server Name]/", "");
                webName = webName.Replace("/default.aspx", "");
    
                SPWeb web = site.AllWebs[webName];
    
                // Reference the new list "StaffList" (as defined in onet.xml).
                SPList list = web.Lists["StaffList"];
    
                // Get the string entered in the listbox, split it up.
                // String format: ("XXXXXX: First Last") 
                string fullName = ListBox1.SelectedItem.Text; 
                string[] splitStr = fullName.Split(':');
    
                string longitude = "";
                string latitude = "";
                // Iterate through list, get the latitude/longitude 
                // values for the selected employee's StaffNumber.
                foreach (SPListItem item in list.Items)
                {
                    if (splitStr[0] == item["StaffNumber"].ToString())
                    {
                        longitude = item["Longitude"].ToString();
                        latitude = item["Latitude"].ToString();
    
                        break;
                    }
                }
    
                // Fetch the Bing map based on the selected employee's 
                // latitude and longitude.
                ShowMap(longitude, latitude); 
            }
    
            public void ShowMap(string Longitude, string Latitude)
            {
                Image2.ImageUrl = GetMap(Latitude, Longitude, Latitude + "," 
                    + Longitude);
            }
    
            private string GetMap(string Latitude, string Longitude, string locationString)
            {
                // Set the address to the Bing Maps imagery service.
                EndpointAddress address = new 
                    EndpointAddress("http://dev.virtualearth.net/webservices/v1/imageryservice/imageryservice.svc");
    
                // Set up the binding, channel, and Bing Maps key.
                BasicHttpBinding binding = new BasicHttpBinding();
                binding.UseDefaultWebProxy = true;
                ChannelFactory<IImageryService> factory = 
                    new ChannelFactory<IImageryService>(binding, address);
                IImageryService channel = factory.CreateChannel(address);
                // Add your key below.
                string key = "[Bing Maps key]";
                MapUriRequest mapUriRequest = new MapUriRequest();
    
                // Set credentials using a valid Bing Maps key
                mapUriRequest.Credentials = new ImageryService.Credentials();
                mapUriRequest.Credentials.ApplicationId = key;
    
                // Set the location of the requested image.
                mapUriRequest.Center = new ImageryService.Location();
                string[] digits = locationString.Split(',');
                mapUriRequest.Center.Latitude = double.Parse(digits[0].Trim());
                mapUriRequest.Center.Longitude = double.Parse(digits[1].Trim());
    
                // Set the map style and zoom level.
                MapUriOptions mapUriOptions = new MapUriOptions();
                mapUriOptions.Style = MapStyle.AerialWithLabels;
                mapUriOptions.ZoomLevel = 17;
    
                // Set the size of the requested image in pixels.
                mapUriOptions.ImageSize = new ImageryService.SizeOfint();
                mapUriOptions.ImageSize.Height = 388;
                mapUriOptions.ImageSize.Width = 465;
                mapUriOptions.Style = MapStyle.AerialWithLabels;
    
                mapUriRequest.Options = mapUriOptions;
    
                // Add a pushpin to the current location.
                ImageryService.Pushpin[] MapPins = new ImageryService.Pushpin[1];
                MapPins[0] = new Pushpin();
                MapPins[0].IconStyle = "34";
                MapPins[0].Location = new Location();
                MapPins[0].Location.Latitude = Convert.ToDouble(Latitude);
                MapPins[0].Location.Longitude = Convert.ToDouble(Longitude);
                mapUriRequest.Pushpins = MapPins;
    
                // Open the channel and retrieve the map.
                ((IChannel)channel).Open();
                MapUriResponse mapUriResponse = channel.GetMapUri(mapUriRequest);
                ((IChannel)channel).Close();
                return mapUriResponse.Uri;
    
            }
        }
    }
    

向 default.aspx 页中添加可视 Web 部件

接下来,将可视 Web 部件添加到网站定义的 default.aspx 页中。

向 default.aspx 页中添加可视 Web 部件

  1. 打开 default.aspx 页,并将以下标记添加到 WebPartPages 标记下面。

    <%@ Register Tagprefix="MyWebPartControls" Namespace="TestSiteDef2.SiteDefinition.VisualWebPart1" Assembly="$SharePoint.Project.AssemblyFullName$" %>
    

    此行将名称 MyWebPartControls 与 Web 部件及其代码相关联。 Namespace 参数与 VisualWebPart1Usercontrol.ascx 代码文件中使用的命名空间相同。

  2. 在 </asp:Content> 元素后面,用以下标记替换整个 ContentPlaceHolderId="PlaceHolderMain" 部分及其内容。

    <asp:Content ID="Content1" ContentPlaceHolderId="PlaceHolderMain" runat="server">
        <h1>
            Welcome to Tailspin Toys
        </h1>  
        <MyWebPartControls:VisualWebPart1 runat="server" />
    </asp:Content>
    

    此标记将创建对您先前创建的可视 Web 部件的引用。

运行并部署网站定义解决方案

接下来,运行项目并将其部署到 SharePoint 中。

运行并部署网站定义

  • 按 F5。 Visual Studio 将编译代码、添加项目功能、将所有文件打包到一个 .wsp 文件中,并将该 .wsp 文件部署到 SharePoint Server。 然后 SharePoint 会安装文件、激活功能并显示**“新建 SharePoint 网站”**页。

基于网站定义创建网站

使用新网站定义创建新网站。

使用网站定义创建网站

  1. 在 SharePoint 网站上,将出现**“新建 SharePoint 网站”**页。

  2. 在**“标题和说明”**部分中,输入“我的新网站”作为标题并输入有关网站的说明。

  3. 在**“网站地址”部分中,将 mynewsite 输入到“URL 名称”**框中。

  4. 在**“模板”部分中,单击“SharePoint 自定义设置”选项卡,然后选择“选择模板”列表中的“TestSiteDef2”**。

  5. 将其他设置保留为其默认值,然后单击**“创建”**。

    新网站将出现。

测试新网站

接下来,将测试新网站以确保它能够正常工作。

测试新网站

  1. 在**“区域”**下方的框中单击某个位置。

    该区域的某个雇员姓名将出现在**“人员”**列表中。

  2. 在**“人员”**列表中单击雇员姓名。

    该雇员的地图位置将出现在图像控件中。

    提示

    如果 Bing 地图服务不可用,则您会收到“EndPointNotFoundException”错误。 如果发生这种情况,请稍后重试。

请参见

任务

演练:创建基本网站定义项目

如何:创建事件接收器

其他资源

开发 SharePoint 解决方案