🦁

Sitecore XM/XP 10.2 に最小構成の Web API を追加する方法

2022/08/19に公開

Sitecore の XM または XP に保存されているデータを外部のサイトで利用したいというシチュエーションは多々あると思います。Sitecore XM/XP 上にカスタマイズした Web API の追加方法をステップバイステップで解説します。

使用環境

  • Visual Studio 2019 以上(筆者環境は Visual Studio 2022 英語版)
  • .NET Framework 4.8
  • Windows 10
  • Sitecore XM/XP 10.2

対象者

  • Sitecore デベロッパー

事前準備

NuGet のパッケージソースに Sitecore を追加

Visual Studio の設定を開きます。

  1. Package Sources を選択
  2. +をクリック
  3. 追加された Package srouces を選択
  4. Name に Sitecore を入力。Source に https://sitecore.myget.org/F/sc-packages/api/v3/index.json を入力
  5. Update をクリック
  6. OK をクリック

以上です。

完成リポジトリ

以下に完成したソースがありますので、ビルドしてすぐに試すことが可能です。
https://github.com/nnasaki/SimpleWebApi

作成手順

新規ソリューション作成

ASP.NET Web Application(.NET Framework) を選択。ASP.NET Core ではないので注意してください。

Project name を入力します。ここでは SimpleWebApi としています。Framework は .NET Framework 4.8 になっていることを改めて確認してください。

プロジェクトの種類は Empty を選択してください。右側の各チェックはすべてオフにしてください。

Create を押すと新規ソリューション及びプロジェクトの作成は完了です。

NuGet パッケージを追加

Visual Studio の Tools から Nuget Package ManagerPackage Manager Console をクリック

画面下部に Package Manager Console が表示されるので Install-Package Sitecore.Services.Infrastructure と入力

このように Successfully installed と出れば成功です。私の環境では2分ほどかかりました。

コントローラー追加

Controllers のフォルダを追加し、クラスを追加

SimpleWebApiController を入力し、Addをクリック

以下コードを入力

using Sitecore.Services.Infrastructure.Web.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace SimpleWebApi.Controllers
{
    // TODO 本番環境ではCORSの設定を必ず絞ってください。これは全許可となっています。
    [EnableCors(origins: "*", headers: "*", methods: "*")]
    public class SimpleWebApiController : ServicesApiController
    {
        public SimpleWebApiController()
        {
        }

        [HttpGet]
        public string Stats()
        {
            return "ok SimpleWebApi";
        }
    }
}

ルート定義追加

コントローラーと同様の手順です。Pipelines のフォルダを追加し、RegisterHttpRoutes クラスを追加。

以下コードを入力

using System.Web.Http;
using Sitecore.Pipelines;

namespace SimpleWebApi.Pipelines
{
    public class RegisterHttpRoutes
    {
        public void Process(PipelineArgs args)
        {
            GlobalConfiguration.Configure(Configure);
        }
        protected void Configure(HttpConfiguration configuration)
        {
            var routes = configuration.Routes;
            routes.MapHttpRoute("SimpleWebApi.stats", "api/simplewebapi/stats", new
            {
                controller = "SimpleWebApi",
                action = "Stats"
            });

        }
    }
}

コンフィグ追加

階層のあるフォルダ App_Config\Include\ZZZZ_CustomConfigs を作成し、SimpleWebApi.config を追加します。

以下設定を入力

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"
			   xmlns:set="http://www.sitecore.net/xmlconfig/set/"
			   xmlns:role="http://www.sitecore.net/xmlconfig/role/">
  <sitecore>
    <pipelines>
      <initialize>
        <processor
           type="SimpleWebApi.Pipelines.RegisterHttpRoutes, SimpleWebApi" />
      </initialize> 
    </pipelines>
  </sitecore>
</configuration>

デプロイ

ビルドしてできたモジュールをデプロイします

dllをbinに追加

プロジェクトの bin に作成された SimpleWebApi.dll を IIS の C:\inetpub\wwwroot\sitecoresc.dev.local\bin にコピーします。 sitecoresc.dev.local の部分は皆様お使いの環境で書き換えてください。

コンフィグをincludeに追加

プロジェクトに追加した SimpleWebApi.configC:\inetpub\wwwroot\sitecoresc.dev.local\App_Config\Include\ZZZZ_CustomConfigs にコピーします。こちらも同様に sitecoresc.dev.local の部分は皆様お使いの環境で書き換えてください。

動作確認

API にアクセスする

Sitecore がデプロイされているサイトにブラウザなどでアクセスして確認します。
今回の例では https://sitecoresc.dev.local/api/simplewebapi/stats にアクセスして確認します。

うまくデプロイ出来ていれば、以下のようにシンプルですが "ok SimpleWebApi" が表示されます。

エラーが発生した場合、トラブルシューティングをご覧ください。

まとめ

今回ご紹介したように Sitecore のカスタマイズは簡単にできますので、ぜひお試しください。

トラブルシューティング

私が試しているときに発生したエラーとその対処をまとめておきます。

No type was found that matches the controller named 'MinimumTest4'

エラー詳細

{"Message":"No HTTP resource was found that matches the request URI 'https://sitecoresc.dev.local/api/minimumtest4/stats'.","MessageDetail":"No type was found that matches the controller named 'MinimumTest4'."}

解決策

2パターンあります。

1. MapHttpRoute にてコントローラー名の設定が間違っている

コントローラー名が間違っていないか確認してください。 MinimumTest4Controller がコントローラー名の場合、 Controller を除いた MinimumTest4 までを指定します。

2. Web.config にて optimizeCompilations="true" を有効にしている

Web.config にて <compilation defaultLanguage="c#" debug="true" targetFramework="4.8" optimizeCompilations="true"> のように optimizeCompilationstrue の場合、optimizeCompilations="false" にしてください。

optimizeCompilations はモジュールの更新時の再リロードを高速化できる機能ですが、新規のパイプラインプロセッサが認識されない場合があります。通常は false にしておいたほうが良いでしょう。

A route named 'MinimumTestApi.stats' is already in the route collection. Route names must be unique.

エラー詳細

Server Error in '/' Application.
A route named 'MinimumTestApi.stats' is already in the route collection. Route names must be unique.
Parameter name: name
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: A route named 'MinimumTestApi.stats' is already in the route collection. Route names must be unique.
Parameter name: name

Source Error:

An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.

解決策

別なモジュールと MapHttpRoute の定義名が被っているため。 RegisterHttpRoutes.csMapHttpRoute の定義名を変更してください。

"Multiple types were found that match the controller named 'MinimumTestApi'

エラー詳細

{"Message":"An error has occurred.","ExceptionMessage":"Multiple types were found that match the controller named 'MinimumTestApi'. This can happen if the route that services this request ('api/minimumtest3/stats') found multiple controllers defined with the same name but differing namespaces, which is not supported.\r\n\r\nThe request for 'MinimumTestApi' has found the following matching controllers:\r\nMinimumTest.Controllers.MinimumTestApiController\r\nMinimumTest.Controllers.MinimumTestApiController","ExceptionType":"System.InvalidOperationException","StackTrace":"   at System.Web.Http.Dispatcher.DefaultHttpControllerSelector.SelectController(HttpRequestMessage request)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"}

解決策

別なモジュールとコントローラーのクラス名が重複があるため名前解決が出来ていない。コントローラーのクラス名を別なものに変更する。

Discussion