Kobarin's Development Blog

C#やASP.NETなどについての記録です。

Umbraco+ASP.NET MVCによるサイト作成

UmbracoとMVCの併存サイトを作ったのでメモします。
まずは当方の環境から。

はじめに

まず参考にさせていただいたのは以下の記事です。
www.buildinsider.net
この記事ではUmbracoのバージョンは6.1.1、MVCはver.4なので、やや古い印象はありますが概ね内容通り進めれば問題ないと思いますが、幾つか追加事項があるのでそれも含めて説明していきます。

A. 新規Webサイトの作成

  1. Visual Studio 2017(以降、VSと略)で新規プロジェクトを作成し、「ASP.NET Web Application (.NET Framework)」を選択
  2. テンプレートから「MVC」を選択
  3. これで空のMVCサイトが出来上がりましたが、この後Umbracoインストール時に上書きされる、ルート直下のweb.configを何処かにバックアップしておきましょう

B. Umbracoのインストー

  1. メニューの[Tools] → [Nuget Package Manager] → [Manage Nuget Packages for Solution]
  2. 「UmbracoCMS」を検索し、プロジェクトに[Install]
  3. ここまでが参考記事2までに沿った流れです

C. web.configの編集

  1. Umbracoによるweb.configとMVCのweb.config(A-3でバックアップしたファイル)をマージする(参考記事3の箇所)。1つ1つタグを追っていき、互いに存在しない行を付け足していきます。

D. 初期設定

  1. プロジェクトをBuildし、[Debug] → [Start Without Debugging]でサイトを起動
  2. この時、web.config周りでエラーが出たら、いったんコメントアウトして再度試してみましょう(私の場合も、忘れましたが幾つか削除しました)
  3. ブラウザが開き、ログインアカウントの設定画面が出ます。そのまま[Install]するとSQL Server Compact EditionとしてApp_Dataフォルダの下の.sdfファイルをデータベースとして使うことになります。SQL serverを使う場合は、[Customize]を押すとサーバー設定が出来ます。後々SQLserverで動作させる予定があるならこの場で設定しておきましょう。なお、後からweb.configのConnetionStringを変更しても上手く動作しませんでした(初期画面の女性が多く写った写真を背景にインジケーターがずっと点滅した場が続きました)。おそらくCEからSQLへのデータ移行を行う必要があるのかもしれません。

E. ルーティング設定

ASP.NET MVCアプリケーションの場合、既定では例えば http://example.jp/Product/Details/123 というアドレスを指定すると、Controller=Product、のAction=Details、id=123 としてルーティングされます。
しかしUmbracoをインストールしたことによりこのルーティング設定は無効化され、あらゆるアクセスがUmbracoで処理されることになります(RouteConrigが削除されたり書き換えられるわけではありません)。
本稿はMVCとの併存サイトを構築することが狙いなので、MVCアプリケーションにもアクセスできるようカスタムルーティングを設定する必要があります。
Umbracoを扱う以上は、基本は全てUmbracoで処理する事になると思われます。その中で、例えば「オンラインショップ部分のみMVCで動かしたい」と考えた場合、http://example.jp/onlineshop/で始まるをMVCアプリケーションとしてルーティング設定することになります。
参考記事5の通り、どこでも良いのでクラスファイルを作り、以下のように作成(参考記事ではGlobal.asax内だが、当方はApp_Code内に記載した)。
Global.asaxのApplication_Start内の文をOnApplicationStarted内に記述。

public class AppStart : IApplicationEventHandler
{
  public void OnApplicationInitialized(UmbracoApplicationBase umbracoApplication,
  ApplicationContext applicationContext)
  { }

  public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication,
     ApplicationContext applicationContext)
  {
  }

  public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
  {
    AreaRegistration.RegisterAllAreas();
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
  }
}

次に、App_Start/RouteConfig.csを開き、以下のように書き直す。

public static void RegisterRoutes(RouteCollection routes)
{
  routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
 
  routes.LowercaseUrls = true;  //小文字の有効化

  routes.MapRoute(
    name: "OnlineShop",
    url: "OnlineShop/{action}/{id}",
    defaults: new { controller = "OnlineShop", action = "Index", id = UrlParameter.Optional },
    namespaces: new[] { "(アプリケーション名).Controllers" }
  );
}

これにより、/onlineshop/で始まるアドレスのみMVCアプリケーションとして動作する事になります。
ちなみにnamespace部分は必ずしも必要ではなく、参考記事にも書かれていません。
ただ、当方の場合プロジェクト名を途中で変更したせいか旧プロジェクトのControlerが残ってしまったらしく、以下のような例外が発生してしまってました。

Multiple types were found that match the controller named 'OnlineShop'. This can happen if the route that services this request ('OnlineShop/{action}/{id}') does not specify namespaces to search for a controller that matches the request. If this is the case, register this route by calling an overload of the 'MapRoute' method that takes a 'namespaces' parameter.

特に必要なければそのままでよいですが、もし上のようなエラーが現れる場合は、MapRouteでnamespaceを付け加えてみて下さい。
これについては、自分なりに探して以下に情報を参考にしました。
stackoverflow.com

F. UmbracoReservedPathsの設定

最後に、参考記事にもあるようにweb.configのappSettings内のUmbracoReservedPathsに以下のように追記して終了です。

<add key="umbracoReservedPaths" value="~/umbraco,~/install/,~/Content,~/Bundles"  />

以上で動作すると思われます。