次の方法で共有


概要

Visual Studio 2010 の SharePoint 開発用ツール

Steve Fox

多くの開発者にとって SharePoint の開発はちょっと謎めいていて、このプラットフォームの開発は煩雑で手の届かないものだと感じているようです。開発者のコミュニティでも、開発にどのツールセットを使うかで意見が分かれています。たとえば、クラス ライブラリ、XML 構成ファイルによって手動で構成されるプロジェクト フォルダー、およびビルド後の出力イベントを組み合わせて、SharePoint 向けの機能やソリューションを生成している開発者もいます。一方、STSDEV、コミュニティ ツール、Visual Studio Extensions for Windows SharePoint Services (VSeWSS) などを使用して、さまざまなアプリケーションやソリューションをビルドし、それらを SharePoint に配置している開発者もいます。つまり、機能やソリューション パッケージを SharePoint に配置する場合、開発者は多種多様な方法を採用できます。さまざまな課題があるにもかかわらず、SharePoint 開発者のコミュニティはかなりの数 (約 600,000 人の開発者) にまで増加し、今後も増え続けると考えられます。将来に目を向けると、Visual Studio 2010 に同梱されるかたちで新しい SharePoint ツールが開発者に届けられ、SharePoint 開発に携わるすばらしいきっかけがもたらされます。

SharePoint 2010 は開発プラットフォームとしての重要な一歩です。というのも、このプラットフォームがたくさんの機能セットをサポートするだけでなく、一連のツールに大きな投資が行われ、開発プロセスの生産性を高め、あらゆるスキル レベルの開発者が利用しやすくなるようにデザインされているためです。SharePoint 2010 には、SharePoint Designer 2010 と Visual Studio 2010 という 2 つの主要開発ツールがあります (デザイナー用の付属のツールセットに Expression スイートもあります)。この記事では、SharePoint 2010 での開発の概要を示し、(新しいプロジェクト テンプレートの簡単な紹介を含めて) Visual Studio 2010 の SharePoint ツールを紹介し、サンプルのビジュアル Web パーツ (Visual Web Part) の作成方法と配置方法について説明します。

Visual Studio 2010 における SharePoint ツール

Visual Studio 2010 には、SharePoint 開発者にとって価値ある領域がいくつかあります。第 1 に、SharePoint のプロジェクト テンプレートがいくつか既定で組み込まれているため、ソリューションの開発にすぐに着手できます。第 2 に、Windows SharePoint Package (WSP) のパッケージ化標準に基づいてツールが標準化されているため、SharePoint にインポートまたは配置されるソリューションは、Visual Studio ではソリューション パッケージとして扱われます。第 3 に、ソリューションの取り消しやカスタム配置構成など、配置やパッケージ化の優れた機能の一部が、Visual Studio 2010 の SharePoint ツールに付属しています。最後に、新しい SharePoint Explorer により、SharePoint サーバー上に存在するネイティブの成果物やカスタム成果物 (リストやワークフローなど) へのビューが提供されます。もちろん、ここで紹介するのは Visual Studio ツールセットの主な拡張機能のほんの一例です。こうした機能は、コミュニティに影響を及ぼし、SharePoint 開発者が容易に行動を起こせるようにデザインされています。

SharePoint 2010 に行われたいくつかの機能強化も取り上げておく価値があるでしょう。強化された機能は、当然ながら Visual Studio 2010 のコンテキスト内で使用できます。たとえば、新しいクライアント オブジェクト モデルを使うと、Web サービス呼び出しではなく、参照先の DLL を通じて SharePoint オブジェクトにアクセスできます (SharePoint 2007 では、たとえば、ASP.NET Web サービスを使用して、SharePoint リストのデータにアクセスしていました)。さらに、LINQ for SharePoint により LINQ to SharePoint の機能がもたらされ、たとえば、厳密に型指定されたオブジェクトとしてリストを扱うことができるようになります。そのうえ、SharePoint 2010 では Silverlight が ネイティブにサポートされるようになりました (特にクライアント オブジェクト モデルと組み合わせて使用します)。その結果、Silverlight の開発に着手するにあたって、web.config の扱いに混乱を生じることがなくなります。ソリューションがサンドボックス化されるため、、SharePoint Web パーツをビルドして、サイトに配置する際に、管理者の手を煩わせる必要がなくなります。つまり、SharePoint サイトに Web パーツを配置し、SharePoint の設置型インスタンス内でも、ホスト型のインスタンスを使用するクラウド内でも、配置したサイトのコンテキスト内でアプリケーションを実行できます。最後に、外部データ リストにより、基幹業務システムとの対話が読み取り/書き込みのプロセスになります。ささいなことのようですが、基幹業務の統合の迅速かつ効果的に行えるようにするツールがサポートされることは大きな前進だと言えます。SharePoint 2010 に加えられたこのような技術革新の 1 つ 1 つに対し、Visual Studio 2010 では、プロジェクト テンプレートや API を通じて、プロフェッショナル開発者向けになんらかのサポートが提供されます。では、SharePoint 開発について説明しましょう。

ビジュアル Web パーツ プロジェクトの開発

開発者が SharePoint で構築ドおよび配置する成果物の中で最も一般的なのが Web パーツです。Web パーツが SharePoint の主な構成要素の 1 つであることを考えると、これは当然です。SharePoint は ASP.NET を基盤として構築されているため、Web パーツは ASP.NET Web パーツのアーキテクチャから主な機能を継承します。

Visual Studio 2010 の新しいプロジェクト テンプレートの 1 つが、"Visual Web Part" (ビジュアル Web パーツ) プロジェクト テンプレートです。開発者はこのテンプレートを使用して、SharePoint に配置可能な Web パーツを視覚的にデザインできます。SharePoint をあまり使われたことがなければ、これは SharePoint 2010 向けにカスタム アプリケーションを構築するよい機会になるでしょう。ここで紹介するビジュアル Web パーツには、製品コストを計算し、その情報を単純な Web パーツ UI に一覧する自己完結型コードが含まれています。


図 1 SharePoint の新しいプロジェクト テンプレート


図 2 ビジュアル Web パーツのデザイナー ビュー

64 ビット版 Windows Server 2008 に Visual Studio 2010 ベータ 2 と SharePoint 2010 ベータ 2 をインストールします。次に、Visual Studio 2010 を起動して、[File] (ファイル)、[New Project] (新しいプロジェクト) の順にクリックし、[Installed Templates] (インストールされたテンプレート) セクションの [SharePoint] ノードに移動します。図 1 は、使用可能なさまざまな種類のプロジェクト テンプレートを示します。たとえば、[Import VSeWSS Project] (VSeWSS プロジェクトのインポート) テンプレートでは、現在の VSeWSS プロジェクトからのアップグレード パスが提供されます。ワークフロー関連のテンプレートでは、ワークフロー プロジェクトを作成して SharePoint に配置できます。[Site Definition] (サイト定義) テンプレートでは、構築および配置が可能なサイト レベルのインフラストラクチャが提供されます。[Import SharePoint Solution Package] (SharePoint ソリューション パッケージのインポート) テンプレートでは、WSP をインポートして、ローカル サーバー インスタンスに再配置できます。ここでは、[Visual Web Part] (ビジュアル Web パーツ) プロジェクト テンプレートを選択し、プロジェクトの名前 (SampleWebPartProject など) と場所を指定してから、[OK] をクリックします。

プロジェクトの作成後に、Visual Studio 2010 により既定のファイルがいくつか作成されます。ソリューション エクスプローラーでそのプロジェクトのノードを展開すると、作成されたファイルが表示されます。この記事で操作する主なファイルは、[SampleWebPartProject] ノードにあるファイルです。既定のビジュアル Web パーツは、"VisualWebPart1" という名前になります。これを変更するには、ソリューション エクスプローラーで [VisualWebPart1] ノードを右クリックし、[Rename] (名前の変更) をクリックしてから、Web パーツの新しい名前を入力します。

また、ソリューション エクスプローラーには [Features] (機能) ノードと [Package] (パッケージ) ノードがあります。Visual Studio 2010 のインフラストラクチャには、SharePoint の機能を使用して SharePoint ソリューションをパッケージ化する、新しい部分があります。SharePoint を使い慣れていない開発者向けに、SharePoint が認識できる方法でアプリケーションを編成する機能が用意されています。たとえば、サイト レベルまたは Web レベルで SharePoint に機能を配置できます。機能は、一連の XML 構成ファイルを通じて構造化され、グローバル アセンブリ キャッシュ (GAC) からのアセンブリを (アプリケーションの信頼レベルに応じて) 参照します。具体的には、SharePoint のフォルダー階層内に機能ごとに独自のフォルダーがあり、そのフォルダー内に構成ファイルが存在し、必要なメタデータが提供されます。パッケージには、機能とその他の資産が含まれ、ソリューションを SharePoint に配置する際に使用されます。パッケージは、アセンブリの配置場所も決定します。Visual Studio 2010 では、パッケージ デザイナーが導入され、パッケージの表示や管理がこれまでよりもはるかに容易になります。[Package] (パッケージ) ノードをダブルクリックすると、デザイナーが起動します。このデザイナーでは、配置可能なパッケージに機能を追加したり、削除したりできるようになります。このデザイナーは、開発者が機能を追加することによって SharePoint ソリューションを強化できるという点で、重要な一歩であると言えます。

ソリューション エクスプローラー ビューに切り替え、[ProductInfoUserControl.ascx] ファイルを右クリックして、[View in Designer] (デザイナーで表示) をクリックします。これにより、ツールボックスからコントロールをドラッグして、Web パーツのデザイナー画面にドロップできるビューが開きます。デザイン ビュー、分割ビュー、およびコード ビューという 3 つのビューがあることがわかります。この例では、タイトルを (入力して) 追加し、製品のコストを計算するための複数のテキスト ボックスと 1 つのボタンなど、いくつかのコントロールを追加しました。ページに追加されたコントロールのラベルにも値を入力しました (図 2 参照)。

ビジュアル Web パーツのレイアウトが完成したら、ボタンのイベント ハンドラーを追加します。その前に、ビジュアル Web パーツのソース コードを少し見てみましょう。図 3 のコードの抜粋からわかるように、Visual Studio では CSS 構文という形式でいくつかのスタイルが UI に自動的に追加されます。また、UI を構成する実際のコントロール (ドロップダウン リストの場合は、アイテムのコレクション) も確認できます。簡潔にするために、ソース コードの先頭に自動生成されていたディレクティブは削除しています。

Web パーツにイベント ハンドラーを追加するには、イベント ハンドラーを作成するボタンをダブルクリックします。すると、分離コードが表示されます。また、ASCX コントロールのデザインに onClick イベントも追加されます。たとえば、図 3 では、btnCalcPrice 内に onclick="btnCalcPrice_Click" イベントが含まれています。図 4 に示す分離コードには、リスト ボックスで選択される製品価格を計算できる簡単な数行のコードが含まれています。このコードで重要なのは、製品コストを計算するのに使用する方法を示すクラス レベルの変数 (double)、lstOfProducts (製品リスト) コレクション (リスト ボックスに追加されるいくつかの Products オブジェクトを保持)、および btnCalcPrice_Click イベントです。SharePoint にページが読み込まれるときに、generateProductList メソッドが呼び出され、リスト ボックスが設定されます。その後、btnCalcPrice_Click イベントにより、(ユーザーが選択した項目に応じて) 特定の製品のコストが計算され、UI のリスト ボックスに情報が表示されます。

図 3 SalaryCalcWebPartUserControl.ascx のソース コード

<style type="text/css">
.style1
{
font-family: Calibri;
font-size: medium;
font-weight: bold;
}
.style2
{
font-family: Calibri;
font-size: small;
font-weight: bold;
}
</style>
<p class="style1">
Product Catalog</p>
<p class="style2">
Product:  
<asp:DropDownList ID="dropdwnProducts" 
runat="server" Height="20px"
style="margin-left: 21px" Width="200px">
<asp:ListItem>Helmet</asp:ListItem>
<asp:ListItem>Stick</asp:ListItem>
<asp:ListItem>Skates</asp:ListItem>
<asp:ListItem>Elbow Pads</asp:ListItem>
<asp:ListItem>Kneepads</asp:ListItem>
</asp:DropDownList>
</p>
<p class="style2">
Description: <asp:TextBox ID="txtbxDescription" runat="server"
Width=”200px” Enabled=”False”></asp:TextBox>
</p>
<p class="style2">
SKU:
<asp:TextBox ID="txtbxSKU" runat="server" style="margin-left: 48px"
Width="200px" Enabled="False"></asp:TextBox>
</p>
<p class="style2">
Price:<asp:TextBox ID="txtbxPrice" runat="server"
style="margin-left: 48px"
Width="200px" Enabled="False"></asp:TextBox>
</p>
<p class="style2">
Quantity:
<asp:TextBox ID="txtbxQuantity" runat="server" 
Width="200px" Enabled="False"></asp:TextBox>
</p>
<p class="style1">
<asp:Button ID="btnCalcPrice" runat="server"
onclick="btnCalcPrice_Click"
Text="Calc." />
</p>

ユーザーがボタンをクリックすると、Web パーツがポストバックを行い、イベントを実行します。ここで、製品コストが計算されます。図 4 のコードは実に単純ですが、おそらくコードよりも興味深い点は、実際の Web パーツ画面が表示されるしくみでしょう。スキンおよび分離コードを含む、Web パーツの ASP ユーザー コントロールを作成したことを考えると、プロジェクトの構造には、このコントロールを表示する実際の Web パーツが依然として含まれていることになります。このために、Visual Studio では _ascxPath という文字列が作成され、SharePoint 2010 のフォルダー階層内にある ASCX ユーザー コントロールへのパスを表します。また、CreateChildControls メソッドでは、コントロールのインスタンスが作成され、(LoadControl メソッドを使用することで) ユーザー コントロールへのパスも設定されます。その後、Add メソッドを使用して Controls コレクションにそのインスタンスが追加されます。これにより、Web パーツが、SharePoint の Web パーツ内で ASP ユーザー コントロールを表示できます。図 5 は、このコードを示しています。

図 4 ProductInfoUserControl.ascx.cs のソース コード

using System;
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Collections.Generic;
using System.Data;
namespace SampleWebPartProject.ProductInfo
{
public partial class ProductInfoUserControl : UserControl
{
double tax = .11;
double totalCost = 0.0;
List<Products> lstOfProducts = new List<Products>();
protected void Page_Load(object sender, EventArgs e)
{
generateProductList();
}
private void generateProductList()
{
lstOfProducts.Add(new Products()
{ strName = "Helmet", strDescr = "Hockey helmet.", strSKU =
"KLSONHELMT1224", dblPrice = 59.00, intQuantity = 28 });
lstOfProducts.Add(new Products()
{ strName = "Skates", strDescr = "Hockey skates.", strSKU =
"SKATWOKSH0965", dblPrice = 438.00, intQuantity = 88 });
lstOfProducts.Add(new Products()
{ strName = "Stick", strDescr = "Composite hockey stick.",
strSKU = "STIK82910JJKS", dblPrice = 189.99, intQuantity =
35 });
lstOfProducts.Add(new Products()
{ strName = "Elbow Pads", strDescr = "Hockey elbow pads.",
strSKU = "ELBOP563215NN", dblPrice = 34.00, intQuantity =
12 });
lstOfProducts.Add(new Products()
{ strName = "Knee Pads", strDescr = "Hockey knee pads.",
strSKU = "KPDS7827NNJS1", dblPrice = 47.99, intQuantity =
44 });
}
protected void btnCalcPrice_Click(object sender, EventArgs e)
{
double dblCost = 0;
string strPrice = "";
if (dropdwnProducts.SelectedValue == "Helmet")
{
dblCost = lstOfProducts[0].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[0].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[0].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[0].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Skates")
{
dblCost = lstOfProducts[1].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[1].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[1].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[1].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Stick")
{
dblCost = lstOfProducts[2].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[2].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[2].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[2].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Elbow Pads")
{
dblCost = lstOfProducts[3].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[3].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[3].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[3].intQuantity.
ToString();
}
else if (dropdwnProducts.SelectedValue == "Knee Pads")
{
dblCost = lstOfProducts[4].dblPrice;
totalCost = dblCost + (dblCost * tax);
System.Math.Round(totalCost, 2);
strPrice = "$" + totalCost.ToString();
txtbxDescription.Text = lstOfProducts[4].strDescr.
ToString();
txtbxSKU.Text = lstOfProducts[4].strSKU.ToString();
txtbxPrice.Text = strPrice;
txtbxQuantity.Text = lstOfProducts[4].intQuantity.
ToString();
}
}
}
}

図 5 ProductInfo.cs のソース コード

using System;
using System.ComponentModel;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
namespace SampleWebPartProject.ProductInfo
{
public class ProductInfo : WebPart
{
private const string _ascxPath =
@"~/CONTROLTEMPLATES/SampleWebPartProject/ProductInfo/" +
@"ProductInfoUserControl.ascx";
public ProductInfo()
{
}
protected override void CreateChildControls()
{
Control control = this.Page.LoadControl(_ascxPath);
Controls.Add(control);
base.CreateChildControls();
}
protected override void Render(HtmlTextWriter writer)
{
base.RenderContents(writer);
}
}
}

図 6 ProductInfo.webpart の XML ファイル

<?xml version="1.0" encoding="utf-8"?>
<webParts>
<webPart xmlns="https://schemas.microsoft.com/WebPart/v3">
<metaData>
<type name="SampleWebPartProject.ProductInfo.ProductInfo,
SampleWebPartProject, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=db3a9f914308c42a" />
<importErrorMessage>
$Resources:core,ImportErrorMessage;
</importErrorMessage>
</metaData>
<data>
<properties>
<property name="Title" type="string">
Product Info Web Part</property>
<property name="Description" type="string">Provides some
information about hockey products.</property>
</properties>
</data>
</webPart>
</webParts>

これでビジュアル Web パーツが構築されたので、これを SharePoint サーバーに配置できます。プロジェクトを作成したときに、特定のサーバー インスタンスに関連付けられるようにプロジェクトを構成しました。つまり、記述したコードと SharePoint サーバーを結び付けるために、なんらかのプログラミング作業が必要です。ソリューション エクスプローラーのファイルを確認すると、この統合に役立ついくつかの XML ファイルがあります。たとえば、Feature.xml ファイルでは、機能の定義が提供されます (次のコード参照)。XML を見ると、このファイルが、Web パーツに関する具体的な情報を提供する他のいくつかの XML ファイルを参照していることがわかります。次のコードでは、Elements.xml と ProductInfo.webpart が参照されていることがわかります。

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="https://schemas.microsoft.com/sharepoint/" 
Id="416172c1-cfa7-4d7a-93ba-fe093b037fab" 
ImageUrl="" Scope="Site" Title="SampleWebPartProject Feature1">
  <ElementManifests>
    <ElementManifest Location="ProductInfo\Elements.xml" />
    <ElementFile Location="ProductInfo\ProductInfo.webpart" />
  </ElementManifests>

Elements.xml では、機能に含まれるコア アセンブリに関する情報が提供され、ProductInfo.webpart では、Web パーツに関するメタデータ (タイトルや説明など) が定義されます。たとえば、図 6 では、既定の Title プロパティと Description プロパティが示されています。これらのプロパティを更新して、Web パーツ ギャラリーに公開される Web パーツのメタデータをわかりやすく表現できます。この Web パーツの場合は、タイトルを "製品情報 Web パーツ" に修正して、説明を "計算された製品価格と情報を提供する Web パーツ" のように変更できます。


図 7 Web パーツ ページの Web パーツ

XML 構成ファイルは他にもあります。SharePoint 開発に慣れていない方は、プロジェクトの各 XML 構成ファイルを確認して、その目的を理解することをお勧めします。では、SharePoint サーバーに Web パーツを配置しましょう。

ビジュアル Web パーツ プロジェクトの配置

SharePoint 2010 以前は、コマンドラインから起動する管理ツールの Stsadm を使用して、SharePoint にアプリケーションを配置するのが一般的でした。Visual Studio 2010 では、この操作を行う必要はありません (Window PowerShell が導入されています。Window PowerShell については、個別の記事で紹介するだけの価値があります)。プロジェクトでは既に SharePoint サーバーとのリレーションシップが確立され、その関連付けには定義済みの信頼レベルが備わっているため、必要な操作は、プロジェクトを右クリックして [Build] (ビルド) をクリックし、ソリューションがビルドされたことを確認してから、そのソリューションを右クリックし [Deploy] (配置) をクリックするだけです。もちろん、F5 キーを押して、SharePoint ソリューションをデバッグすることもできます。デバッグの操作には、適切なプロセスへのアタッチや IIS のリセットなどの手順があります。

Web パーツが正常に配置されたら、SharePoint サイトを開いて新しい Web パーツ ページを作成する必要があります。F5 キーを押してアプリケーションのデバッグを行った場合は、[Create Web Part] (Web パーツの作成) ページが既定で呼び出されます。それ以外の場合は、[View All Site Content] (すべてのサイト コンテンツの表示) をクリックして、[Create] (作成) をクリックします。[Web Part Page] (Web パーツ ページ) オプションをクリックして、その特定の Web パーツ ページに関する必要な情報を入力します。たとえば、そのページの名前やレイアウト テンプレートを入力します。この情報を入力して、[Create] (作成) をクリックすると、SharePoint によって Web パーツ ページが作成されます。

ここで、作成してサーバーに配置したビジュアル Web パーツを追加する必要があります。これを行うには、Web パーツ ページに移動して、[Site Actions] (サイトの操作) をクリックし、[Edit Page] (ページの編集) をクリックします。ビジュアル Web パーツを配置する Web パーツ領域をクリックし、[Insert] (挿入) タブをクリックして、[Insert] (挿入) タブで Web パーツをクリックします。

この操作が完了したら、いくつかの Web パーツのカテゴリが表示されます。ここで、特定の Web パーツを参照して選択し、ページ上で選択した Web パーツ領域に追加できます。[Custom] (カスタム) カテゴリに移動すると、[Web Parts] (Web パーツ) ペインに、作成して配置したビジュアル Web パーツが表示されます。この記事のコードをそのまま使用している場合は、[ProductInfo] Web パーツをクリックして、[Add] (追加) をクリックします。

これで、Web パーツ ページの Web パーツ領域に Web パーツが追加されます (図 7 参照)。この時点で、[Tools] (ツール) ペインを使用して Web パーツのオプションを構成するか、既定のオプションをそのまま使用して [Stop Editing] (編集の終了) をクリックするかを選択できます。

SharePoint 開発への取り組み

Visual Studio 2010 は、SharePoint 開発者向けに一連のネイティブ ツールを提供するだけでなく、SharePoint 開発に携わるすばらしい機会も提供します。そのため、これらのツールを確認してみることをお勧めします。コードを管理したい開発者や、デザインすることが好きな開発者向けにいくつかの優れたオプションが用意されているため、SharePoint ですばらしいソリューションを構築および配置できます。

Steve Fox は、マイクロソフトの開発者プラットフォーム エバンジェリズム (DPE) チームのシニア テクニカル エバンジェリストです。Office および SharePoint 開発の宣伝と、開発作業でこれらを使用する企業との共同作業にほとんどの時間を費やしています。多数の書籍の出版や記事の公開を行っており、世界中の開発者向けカンファレンスで定期的に公演を行っています。